freebsd-libs-10.1~svn273304/0000755000000000000000000000000012421417222012267 5ustar freebsd-libs-10.1~svn273304/lib/0000755000000000000000000000000012421417342013040 5ustar freebsd-libs-10.1~svn273304/lib/libelf/0000755000000000000000000000000012421417242014274 5ustar freebsd-libs-10.1~svn273304/lib/libelf/elf_phnum.c0000644000000000000000000000372111421562272016423 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" static int _libelf_getphdrnum(Elf *e, size_t *phnum) { void *eh; int ec; if (e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (-1); } if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) return (-1); *phnum = e->e_u.e_elf.e_nphdr; return (0); } int elf_getphdrnum(Elf *e, size_t *phnum) { return (_libelf_getphdrnum(e, phnum)); } /* Deprecated API */ int elf_getphnum(Elf *e, size_t *phnum) { return (_libelf_getphdrnum(e, phnum) >= 0); } freebsd-libs-10.1~svn273304/lib/libelf/elf_begin.30000644000000000000000000001503211763446710016305 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 20, 2010 .Dt ELF_BEGIN 3 .Os .Sh NAME .Nm elf_begin .Nd open an ELF file or ar(1) archive .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf *" .Fn elf_begin "int fd" "Elf_Cmd cmd" "Elf *elf" .Sh DESCRIPTION Function .Fn elf_begin is used to open ELF files and .Xr ar 1 archives for further processing by other APIs in the .Xr elf 3 library. It is also used to access individual ELF members of an .Xr ar 1 archive in combination with the .Xr elf_next 3 and .Xr elf_rand 3 APIs. .Pp Argument .Ar fd is an open file descriptor returned from an .Xr open 2 system call. Function .Fn elf_begin uses argument .Ar fd for reading or writing depending on the value of argument .Ar cmd . Argument .Ar elf is primarily used for iterating through archives. .Pp The argument .Ar cmd can have the following values: .Bl -tag -width "ELF_C_WRITE" .It ELF_C_NULL Causes .Fn elf_begin to return NULL. Arguments .Ar fd and .Ar elf are ignored, and no additional error is signalled. .It ELF_C_READ This value is to be when the application wishes to examine (but not modify) the contents of the file specified by argument .Ar fd . It can be used for both .Xr ar 1 archives and for regular ELF files. .Pp Argument .Ar fd should have been opened for reading. If argument .Ar elf is NULL, the library will allocate a new ELF descriptor for the file being processed. If argument .Ar elf is not NULL, and references a regular ELF file previously opened with .Fn elf_begin , then the activation count for .Ar elf is incremented. If argument .Ar elf is not NULL, and references a descriptor for an .Xr ar 1 archive opened earlier with .Fn elf_begin , a descriptor for an element in the archive is returned as described in the section .Sx "Processing ar(1) archives" below. .It Dv ELF_C_RDWR The command is used to prepare an ELF file for reading and writing. It is not supported for archives. .Pp Argument .Ar fd should have been opened for reading and writing. If argument .Ar elf is NULL, the library will allocate a new ELF descriptor for the file being processed. If the argument .Ar elf is non-null, it should point to a descriptor previously allocated with .Fn elf_begin with the same values for arguments .Ar fd and .Ar cmd ; in this case the library will increment the activation count for descriptor .Ar elf and return the same descriptor. Changes to the in-memory image of the ELF file are written back to disk using the .Xr elf_update 3 function. .Pp This command is not valid for .Xr ar 1 archives. .It Dv ELF_C_WRITE This command is used when the application wishes to create a new ELF file. Argument .Ar fd should have been opened for writing. Argument .Ar elf is ignored, and the previous contents of file referenced by argument .Ar fd are overwritten. .El .Ss Processing ar(1) archives An .Xr ar 1 archive may be opened in read mode (with argument .Ar cmd set to .Dv ELF_C_READ ) using .Fn elf_begin or .Fn elf_memory . The returned ELF descriptor can be passed into to subsequent calls to .Fn elf_begin to access individual members of the archive. .Pp Random access within an opened archive is possible using the .Xr elf_next 3 and .Xr elf_rand 3 functions. .Pp The symbol table of the archive may be retrieved using .Xr elf_getarsym 3 . .Sh RETURN VALUES The function returns a pointer to a ELF descriptor if successful, or NULL if an error occurred. .Sh EXAMPLES To iterate through the members of an .Xr ar 1 archive, use: .Bd -literal -offset indent Elf_Cmd c; Elf *ar_e, *elf_e; \&... c = ELF_C_READ; if ((ar_e = elf_begin(fd, c, (Elf *) 0)) == 0) { \&... handle error in opening the archive ... } while ((elf_e = elf_begin(fd, c, ar_e)) != 0) { \&... process member referenced by elf_e here ... c = elf_next(elf_e); elf_end(elf_e); } .Ed .Pp To create a new ELF file, use: .Bd -literal -offset indent int fd; Elf *e; \&... if ((fd = open("filename", O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0) { \&... handle the error from open(2) ... } if ((e = elf_begin(fd, ELF_C_WRITE, (Elf *) 0)) == 0) { \&... handle the error from elf_begin() ... } \&... create the ELF image using other elf(3) APIs ... elf_update(e, ELF_C_WRITE); elf_end(e); .Ed .Sh ERRORS Function .Fn elf_begin can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARCHIVE The archive denoted by argument .Ar elf could not be parsed. .It Bq Er ELF_E_ARGUMENT An unrecognized value was specified in argument .Ar cmd . .It Bq Er ELF_E_ARGUMENT A non-null value for argument .Ar elf was specified when .Ar cmd was set to .Dv ELF_C_RDWR . .It Bq Er ELF_E_ARGUMENT The value of argument .Ar fd differs from the one the ELF descriptor .Ar elf was created with. .It Bq Er ELF_E_ARGUMENT Argument .Ar cmd differs from the value specified when ELF descriptor .Ar elf was created. .It Bq Er ELF_E_ARGUMENT An .Xr ar 1 archive was opened with .Ar cmd set to .Dv ELF_C_RDWR . .It Bq Er ELF_E_IO Function .Fn elf_begin was unable to truncate a file opened for writing using .Dv ELF_C_WRITE . .It Bq Er ELF_E_RESOURCE An out of memory condition was encountered. .It Bq Er ELF_E_SEQUENCE Function .Fn elf_begin was called before a working version was established with .Xr elf_version 3 . .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_end 3 , .Xr elf_errno 3 , .Xr elf_memory 3 , .Xr elf_next 3 , .Xr elf_rand 3 , .Xr elf_update 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/libelf_ar_util.c0000644000000000000000000001251411421567012017417 0ustar /*- * Copyright (c) 2006,2009 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "_libelf.h" /* * Convert a string bounded by `start' and `start+sz' (exclusive) to a * number in the specified base. */ int _libelf_ar_get_number(char *s, size_t sz, int base, size_t *ret) { int c, v; size_t r; char *e; assert(base <= 10); e = s + sz; /* skip leading blanks */ for (;s < e && (c = *s) == ' '; s++) ; r = 0L; for (;s < e; s++) { if ((c = *s) == ' ') break; if (c < '0' || c > '9') return (0); v = c - '0'; if (v >= base) /* Illegal digit. */ break; r *= base; r += v; } *ret = r; return (1); } /* * Retrieve a string from a name field. If `rawname' is set, leave * ar(1) control characters in. */ char * _libelf_ar_get_string(const char *buf, size_t bufsize, int rawname) { const char *q; char *r; size_t sz; if (rawname) sz = bufsize + 1; else { /* Skip back over trailing blanks. */ for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q) ; if (q < buf) { /* * If the input buffer only had blanks in it, * return a zero-length string. */ buf = ""; sz = 1; } else { /* * Remove the trailing '/' character, but only * if the name isn't one of the special names * "/" and "//". */ if (q > buf + 1 || (q == (buf + 1) && *buf != '/')) q--; sz = q - buf + 2; /* Space for a trailing NUL. */ } } if ((r = malloc(sz)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } (void) strncpy(r, buf, sz); r[sz - 1] = '\0'; return (r); } /* * Retrieve the full name of the archive member. */ char * _libelf_ar_get_name(char *buf, size_t bufsize, Elf *e) { char c, *q, *r, *s; size_t len; size_t offset; assert(e->e_kind == ELF_K_AR); if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') { /* * The value in field ar_name is a decimal offset into * the archive string table where the actual name * resides. */ if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, &offset) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } if (offset > e->e_u.e_ar.e_rawstrtabsz) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } s = q = e->e_u.e_ar.e_rawstrtab + offset; r = e->e_u.e_ar.e_rawstrtab + e->e_u.e_ar.e_rawstrtabsz; for (s = q; s < r && *s != '/'; s++) ; len = s - q + 1; /* space for the trailing NUL */ if ((s = malloc(len)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } (void) strncpy(s, q, len); s[len - 1] = '\0'; return (s); } /* * Normal 'name' */ return (_libelf_ar_get_string(buf, bufsize, 0)); } /* * Open an 'ar' archive. */ Elf * _libelf_ar_open(Elf *e) { int i; char *s, *end; size_t sz; struct ar_hdr arh; e->e_kind = ELF_K_AR; e->e_u.e_ar.e_nchildren = 0; e->e_u.e_ar.e_next = (off_t) -1; /* * Look for special members. */ s = e->e_rawfile + SARMAG; end = e->e_rawfile + e->e_rawsize; assert(e->e_rawsize > 0); /* * Look for magic names "/ " and "// " in the first two entries * of the archive. */ for (i = 0; i < 2; i++) { if (s + sizeof(arh) > end) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } (void) memcpy(&arh, s, sizeof(arh)); if (arh.ar_fmag[0] != '`' || arh.ar_fmag[1] != '\n') { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } if (arh.ar_name[0] != '/') /* not a special symbol */ break; if (_libelf_ar_get_number(arh.ar_size, sizeof(arh.ar_size), 10, &sz) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } assert(sz > 0); s += sizeof(arh); if (arh.ar_name[1] == ' ') { /* "/ " => symbol table */ e->e_u.e_ar.e_rawsymtab = s; e->e_u.e_ar.e_rawsymtabsz = sz; } else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') { /* "// " => string table for long file names */ e->e_u.e_ar.e_rawstrtab = s; e->e_u.e_ar.e_rawstrtabsz = sz; } sz = LIBELF_ADJUST_AR_SIZE(sz); s += sz; } e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile); return (e); } freebsd-libs-10.1~svn273304/lib/libelf/elf_getshdrstrndx.30000644000000000000000000000510511734141115020111 0ustar .\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 5, 2009 .Dt ELF_GETSHDRSTRNDX 3 .Os .Sh NAME .Nm elf_getshdrstrndx .Nd retrieve the index of the section name string table .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_getshdrstrndx "Elf *elf" "size_t *ndxptr" .Sh DESCRIPTION Function .Fn elf_getshdrstrndx retrieves the section index of the string table containing section names from descriptor .Ar elf and stores it into the location pointed to by argument .Ar ndxptr . .Pp This function allow applications to process both normal ELF objects and ELF objects that use extended section numbering uniformly. .Sh RETURN VALUES These functions return zero if successful, or -1 in case of an error. .Sh ERRORS These functions can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not for an ELF file. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf lacks an ELF Executable header. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx contained a value in the reserved range of section indices. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getident 3 , .Xr elf_getphdrnum 3 , .Xr elf_getshdrnum 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getident.30000644000000000000000000000504511361411226017013 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd July 3, 2006 .Dt ELF_GETIDENT 3 .Os .Sh NAME .Nm elf_getident .Nd return the initial bytes of a file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft char * .Fn elf_getident "Elf *elf" "size_t *sz" .Sh DESCRIPTION Function .Fn elf_getident returns a pointer to the initial bytes of the file for descriptor .Ar elf . .Pp If argument .Ar sz is non-null, the size of the identification area returned is written to the location pointed to by .Ar sz . This location is set to zero on errors. .Sh RETURN VALUES Function .Fn elf_getident will return a non-NULL pointer to the initial bytes of the file if successful, or NULL if an error condition is detected. .Sh ERRORS Function .Fn elf_getident can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_SEQUENCE ELF descriptor .Ar elf was opened for writing and function .Fn elf_getident was called before a call to .Xr elf_update 3 . .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getarhdr 3 , .Xr elf_getbase 3 , .Xr elf_getflags 3 , .Xr elf_kind 3 , .Xr elf_rawfile 3 , .Xr elf_update 3 , .Xr gelf 3 , .Xr gelf_getclass 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_rand.30000644000000000000000000000606411361411226016136 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 17, 2006 .Dt ELF_RAND 3 .Os .Sh NAME .Nm elf_rand .Nd provide sequential access to the next archive member .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft off_t .Fn elf_rand "Elf *archive" "off_t offset" .Sh DESCRIPTION The .Fn elf_rand function causes the ELF descriptor .Ar archive to be adjusted so that the next call to .Xr elf_begin 3 will provide access to the archive member at byte offset .Ar offset in the archive. Argument .Ar offset is the byte offset from the start of the archive to the beginning of the archive header for the desired member. .Pp Archive member offsets may be retrieved using the .Xr elf_getarsym 3 function. .Sh RETURN VALUES Function .Fn elf_rand returns .Ar offset if successful or zero in case of an error. .Sh EXAMPLES To process all the members of an archive use: .Bd -literal -offset indent off_t off; Elf *archive, *e; \&... cmd = ELF_C_READ; archive = elf_begin(fd, cmd, NULL); while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) { ... process `e' here ... elf_end(e); off = ...new value...; if (elf_rand(archive, off) != off) { ... process error ... } } elf_end(archive); .Ed .Pp To rewind an archive, use: .Bd -literal -offset indent Elf *archive; \&... if (elf_rand(archive, SARMAG) != SARMAG) { ... error ... } .Ed .Sh ERRORS Function .Fn elf_rand may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar archive was null. .It Bq Er ELF_E_ARGUMENT Argument .Ar archive was not a descriptor for an .Xr ar 1 archive. .It Bq Er ELF_E_ARCHIVE Argument .Ar offset did not correspond to the start of an archive member header. .El .Sh SEE ALSO .Xr ar 1 , .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_end 3 , .Xr elf_getarsym 3 , .Xr elf_next 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getident.c0000644000000000000000000000367010525402563017102 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" char * elf_getident(Elf *e, size_t *sz) { if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); goto error; } if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) { LIBELF_SET_ERROR(SEQUENCE, 0); goto error; } assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ); if (sz) { if (e->e_kind == ELF_K_AR) *sz = SARMAG; else if (e->e_kind == ELF_K_ELF) *sz = EI_NIDENT; else *sz = e->e_rawsize; } return (e->e_rawfile); error: if (sz) *sz = 0; return (NULL); } freebsd-libs-10.1~svn273304/lib/libelf/elf_rand.c0000644000000000000000000000364410525402563016224 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" off_t elf_rand(Elf *ar, off_t offset) { struct ar_hdr *arh; if (ar == NULL || ar->e_kind != ELF_K_AR || (offset & 1) || offset < SARMAG || offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { LIBELF_SET_ERROR(ARGUMENT, 0); return 0; } arh = (struct ar_hdr *) (ar->e_rawfile + offset); /* a too simple sanity check */ if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') { LIBELF_SET_ERROR(ARCHIVE, 0); return 0; } ar->e_u.e_ar.e_next = offset; return (offset); } freebsd-libs-10.1~svn273304/lib/libelf/libelf_allocate.c0000644000000000000000000001016710566777536017575 0ustar /*- * Copyright (c) 2006 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. */ /* * Internal APIs */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "_libelf.h" Elf * _libelf_allocate_elf(void) { Elf *e; if ((e = malloc(sizeof(*e))) == NULL) { LIBELF_SET_ERROR(RESOURCE, errno); return NULL; } e->e_activations = 1; e->e_arhdr = NULL; e->e_byteorder = ELFDATANONE; e->e_class = ELFCLASSNONE; e->e_cmd = ELF_C_NULL; e->e_fd = -1; e->e_flags = 0; e->e_kind = ELF_K_NONE; e->e_parent = NULL; e->e_rawfile = NULL; e->e_rawsize = 0; e->e_version = LIBELF_PRIVATE(version); (void) memset(&e->e_u, 0, sizeof(e->e_u)); return (e); } void _libelf_init_elf(Elf *e, Elf_Kind kind) { assert(e != NULL); assert(e->e_kind == ELF_K_NONE); e->e_kind = kind; switch (kind) { case ELF_K_ELF: STAILQ_INIT(&e->e_u.e_elf.e_scn); break; default: break; } } #define FREE(P) do { \ if (P) \ free(P); \ } while (0) Elf * _libelf_release_elf(Elf *e) { switch (e->e_kind) { case ELF_K_AR: FREE(e->e_u.e_ar.e_symtab); break; case ELF_K_ELF: switch (e->e_class) { case ELFCLASS32: FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); FREE(e->e_u.e_elf.e_phdr.e_phdr32); break; case ELFCLASS64: FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); FREE(e->e_u.e_elf.e_phdr.e_phdr64); break; } assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); if (e->e_arhdr) { FREE(e->e_arhdr->ar_name); FREE(e->e_arhdr->ar_rawname); free(e->e_arhdr); } break; default: break; } free(e); return (NULL); } Elf_Data * _libelf_allocate_data(Elf_Scn *s) { Elf_Data *d; if ((d = calloc((size_t) 1, sizeof(Elf_Data))) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } d->d_scn = s; return (d); } Elf_Data * _libelf_release_data(Elf_Data *d) { if (d->d_flags & LIBELF_F_MALLOCED) free(d->d_buf); free(d); return (NULL); } Elf_Scn * _libelf_allocate_scn(Elf *e, size_t ndx) { Elf_Scn *s; if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { LIBELF_SET_ERROR(RESOURCE, errno); return (NULL); } s->s_elf = e; s->s_ndx = ndx; STAILQ_INIT(&s->s_data); STAILQ_INIT(&s->s_rawdata); STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); return (s); } Elf_Scn * _libelf_release_scn(Elf_Scn *s) { Elf *e; Elf_Data *d, *td; assert(s != NULL); STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next); d = _libelf_release_data(d); } STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { assert((d->d_flags & LIBELF_F_MALLOCED) == 0); STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next); d = _libelf_release_data(d); } e = s->s_elf; assert(e != NULL); STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); free(s); return (NULL); } freebsd-libs-10.1~svn273304/lib/libelf/elf_getshdrnum.30000644000000000000000000000472411734141115017374 0ustar .\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 4, 2009 .Dt ELF_GETSHDRNUM 3 .Os .Sh NAME .Nm elf_getshdrnum .Nd return the number of sections in an ELF file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_getshdrnum "Elf *elf" "size_t *shnum" .Sh DESCRIPTION Function .Fn elf_getshdrnum retrieves the number of ELF sections associated with descriptor .Ar elf and stores it into the location pointed to by argument .Ar shnum . .Pp This routine allows applications to uniformly process both normal ELF objects, and ELF objects that use extended section numbering. .Sh RETURN VALUES Function .Fn elf_getshdrnum returns zero value if successful, or -1 in case of an error. .Sh ERRORS Function .Fn elf_getshdrnum can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not for an ELF file. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf lacks an ELF Executable header. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getident 3 , .Xr elf_getphdrnum 3 , .Xr elf_getshdrstrndx 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_ehdr.c0000644000000000000000000001007011421533314016353 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "_libelf.h" Elf32_Ehdr * elf32_getehdr(Elf *e) { return (_libelf_ehdr(e, ELFCLASS32, 0)); } Elf64_Ehdr * elf64_getehdr(Elf *e) { return (_libelf_ehdr(e, ELFCLASS64, 0)); } GElf_Ehdr * gelf_getehdr(Elf *e, GElf_Ehdr *d) { int ec; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; if (d == NULL || e == NULL || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) return (NULL); (void) memcpy(d->e_ident, eh32->e_ident, sizeof(eh32->e_ident)); d->e_type = eh32->e_type; d->e_machine = eh32->e_machine; d->e_version = eh32->e_version; d->e_entry = eh32->e_entry; d->e_phoff = eh32->e_phoff; d->e_shoff = eh32->e_shoff; d->e_flags = eh32->e_flags; d->e_ehsize = eh32->e_ehsize; d->e_phentsize = eh32->e_phentsize; d->e_phnum = eh32->e_phnum; d->e_shentsize = eh32->e_shentsize; d->e_shnum = eh32->e_shnum; d->e_shstrndx = eh32->e_shstrndx; return (d); } assert(ec == ELFCLASS64); if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) return (NULL); *d = *eh64; return (d); } Elf32_Ehdr * elf32_newehdr(Elf *e) { return (_libelf_ehdr(e, ELFCLASS32, 1)); } Elf64_Ehdr * elf64_newehdr(Elf *e) { return (_libelf_ehdr(e, ELFCLASS64, 1)); } void * gelf_newehdr(Elf *e, int ec) { if (e != NULL && (ec == ELFCLASS32 || ec == ELFCLASS64)) return (_libelf_ehdr(e, ec, 1)); LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } int gelf_update_ehdr(Elf *e, GElf_Ehdr *s) { int ec; void *ehdr; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (e->e_cmd == ELF_C_READ) { LIBELF_SET_ERROR(MODE, 0); return (0); } if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (0); (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); if (ec == ELFCLASS64) { eh64 = (Elf64_Ehdr *) ehdr; *eh64 = *s; return (1); } eh32 = (Elf32_Ehdr *) ehdr; (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); eh32->e_type = s->e_type; eh32->e_machine = s->e_machine; eh32->e_version = s->e_version; LIBELF_COPY_U32(eh32, s, e_entry); LIBELF_COPY_U32(eh32, s, e_phoff); LIBELF_COPY_U32(eh32, s, e_shoff); eh32->e_flags = s->e_flags; eh32->e_ehsize = s->e_ehsize; eh32->e_phentsize = s->e_phentsize; eh32->e_phnum = s->e_phnum; eh32->e_shentsize = s->e_shentsize; eh32->e_shnum = s->e_shnum; eh32->e_shstrndx = s->e_shstrndx; return (1); } freebsd-libs-10.1~svn273304/lib/libelf/elf_begin.c0000644000000000000000000000762311421571701016362 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "_libelf.h" static Elf * _libelf_open_object(int fd, Elf_Cmd c) { Elf *e; void *m; struct stat sb; /* * 'Raw' files are always mapped with 'PROT_READ'. At * elf_update(3) time for files opened with ELF_C_RDWR the * mapping is unmapped, file data is written to using write(2) * and then the raw data is immediately mapped back in. */ if (fstat(fd, &sb) < 0) { LIBELF_SET_ERROR(IO, errno); return (NULL); } m = NULL; if ((m = mmap(NULL, (size_t) sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == MAP_FAILED) { LIBELF_SET_ERROR(IO, errno); return (NULL); } if ((e = elf_memory(m, (size_t) sb.st_size)) == NULL) { (void) munmap(m, (size_t) sb.st_size); return (NULL); } e->e_flags |= LIBELF_F_MMAP; e->e_fd = fd; e->e_cmd = c; if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { (void) elf_end(e); LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } return (e); } Elf * elf_begin(int fd, Elf_Cmd c, Elf *a) { Elf *e; e = NULL; if (LIBELF_PRIVATE(version) == EV_NONE) { LIBELF_SET_ERROR(SEQUENCE, 0); return (NULL); } switch (c) { case ELF_C_NULL: return (NULL); case ELF_C_WRITE: if (a != NULL) { /* not allowed for ar(1) archives. */ LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } /* * Check writeability of `fd' immediately and fail if * not writeable. */ if (ftruncate(fd, (off_t) 0) < 0) { LIBELF_SET_ERROR(IO, errno); return (NULL); } if ((e = _libelf_allocate_elf()) != NULL) { _libelf_init_elf(e, ELF_K_ELF); e->e_byteorder = LIBELF_PRIVATE(byteorder); e->e_fd = fd; e->e_cmd = c; } return (e); case ELF_C_RDWR: if (a != NULL) { /* not allowed for ar(1) archives. */ LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } /*FALLTHROUGH*/ case ELF_C_READ: /* * Descriptor `a' could be for a regular ELF file, or * for an ar(1) archive. If descriptor `a' was opened * using a valid file descriptor, we need to check if * the passed in `fd' value matches the original one. */ if (a && ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } break; default: LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (a == NULL) e = _libelf_open_object(fd, c); else if (a->e_kind == ELF_K_AR) e = _libelf_ar_open_member(a->e_fd, c, a); else (e = a)->e_activations++; return (e); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_cap.c0000644000000000000000000000700210541424661016203 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" #if __FreeBSD_version >= 700025 GElf_Cap * gelf_getcap(Elf_Data *d, int ndx, GElf_Cap *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Cap *cap32; Elf64_Cap *cap64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { cap32 = (Elf32_Cap *) d->d_buf + ndx; dst->c_tag = cap32->c_tag; dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val; } else { cap64 = (Elf64_Cap *) d->d_buf + ndx; *dst = *cap64; } return (dst); } int gelf_update_cap(Elf_Data *d, int ndx, GElf_Cap *gc) { int ec; Elf *e; Elf_Scn *scn; Elf32_Cap *cap32; Elf64_Cap *cap64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || gc == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { cap32 = (Elf32_Cap *) d->d_buf + ndx; LIBELF_COPY_U32(cap32, gc, c_tag); LIBELF_COPY_U32(cap32, gc, c_un.c_val); } else { cap64 = (Elf64_Cap *) d->d_buf + ndx; *cap64 = *gc; } return (1); } #endif /* __FreeBSD_version >= 700025 */ freebsd-libs-10.1~svn273304/lib/libelf/elf_flagdata.30000644000000000000000000001110111361411226016741 0ustar .\" Copyright (c) 2006,2007 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd October 22, 2007 .Dt ELF_FLAGDATA 3 .Os .Sh NAME .Nm elf_flagdata , .Nm elf_flagehdr , .Nm elf_flagelf , .Nm elf_flagphdr , .Nm elf_flagscn , .Nm elf_flagshdr .Nd manipulate flags associated with ELF(3) data structures .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "unsigned int" .Fn elf_flagdata "Elf_Data *data" "Elf_Cmd cmd" "unsigned int flags" .Ft "unsigned int" .Fn elf_flagehdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" .Ft "unsigned int" .Fn elf_flagelf "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" .Ft "unsigned int" .Fn elf_flagphdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" .Ft "unsigned int" .Fn elf_flagscn "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" .Ft "unsigned int" .Fn elf_flagshdr "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" .Sh DESCRIPTION These functions are used to query, set or reset flags on data structures associated with an ELF file. .Pp Arguments .Ar data , .Ar elf and .Ar scn denote the data structures whose flags need to be changed. These values are allowed to be NULL to simplify error handling in application code. .Pp Argument .Ar cmd may have the following values: .Bl -tag -width ELF_C_SET .It Dv ELF_C_CLR The argument .Ar flags specifies the flags to be cleared. .It Dv ELF_C_SET The argument .Ar flags specifies the flags to be set. .El .Pp The argument .Ar flags is allowed to have the following flags set: .Bl -tag -width ELF_F_LAYOUT .It Dv ELF_F_DIRTY Mark the associated data structure as needing to be written back to the underlying file. A subsequent call to .Xr elf_update 3 will resynchronize the library's internal data structures. .It Dv ELF_F_LAYOUT This flag is only valid with the .Fn elf_flagelf API. It informs the library that the application will take responsibility for the layout of the file and that the library is not to insert any padding in between sections. .El .Pp Marking a given data structure as .Dq dirty affects all of its contained elements. Thus marking an ELF descriptor .Ar elf with .Fn elf_flagelf "elf" "ELF_C_SET" "ELF_F_DIRTY" means that the entire contents of the descriptor are .Dq dirty . .Pp Using a value of zero for argument .Ar flags will return the current set of flags for the data structure being queried. .Sh RETURN VALUES These functions return the updated flags is successful, and zero if an error is detected. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT An unsupported value was used for the .Ar cmd argument. .It Bq Er ELF_E_ARGUMENT Argument .Ar flags had unsupported flags set. .It Bq Er ELF_E_ARGUMENT The argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_SEQUENCE Function .Fn elf_flagehdr was called without an executable header being allocated. .It Bq Er ELF_E_SEQUENCE Function .Fn elf_flagphdr was called without a program header being allocated. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_newehdr 3 , .Xr elf32_newphdr 3 , .Xr elf32_newshdr 3 , .Xr elf64_newehdr 3 , .Xr elf64_newphdr 3 , .Xr elf64_newshdr 3 , .Xr elf_newdata 3 , .Xr elf_update 3 , .Xr gelf 3 , .Xr gelf_newehdr 3 , .Xr gelf_newphdr 3 , .Xr gelf_newshdr 3 , .Xr gelf_update_dyn 3 , .Xr gelf_update_move 3 , .Xr gelf_update_rel 3 , .Xr gelf_update_rela 3 , .Xr gelf_update_sym 3 , .Xr gelf_update_syminfo 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_getsymshndx.30000644000000000000000000001007311361411226017731 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd November 5, 2006 .Dt GELF_GETSYMSHNDX 3 .Os .Sh NAME .Nm gelf_getsymshndx , .Nm gelf_update_symshndx .Nd read and update symbol information using extended section indices .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Sym *" .Fo gelf_getsymshndx .Fa "Elf_Data *symdata" .Fa "Elf_Data *xndxdata" .Fa "int ndx" .Fa "GElf_Sym *sym" .Fa "Elf32_Word *xndxptr" .Fc .Ft int .Fo gelf_update_symshndx .Fa "Elf_Data *symdata" .Fa "Elf_Data *xndxdata" .Fa "int ndx" .Fa "GElf_Sym *sym" .Fa "Elf32_Word xndx" .Fc .Sh DESCRIPTION These functions are analogous to .Fn gelf_getsym and .Fn gelf_update_sym respectively, but are capable of handling symbol tables using extended section numbering. .Pp Argument .Ar symdata is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_SYMTAB . Argument .Ar xndxdata is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_SYMTAB_SHNDX . Argument .Ar ndx is the index of the symbol table entry being retrieved or updated. Argument .Ar sym is a pointer to a class-independent .Vt GElf_Sym structure. .Vt GElf_Sym structures are described in detail in .Xr gelf 3 . .Pp Function .Fn gelf_getsymshndx retrieves symbol information at index .Ar ndx from the data descriptor specified by argument .Ar symdata and stores in class-independent form in argument .Ar sym . In addition it retrieves the extended section index for the symbol from data buffer .Ar xndxdata and stores it into the location pointed to by argument .Ar xndxptr . .Pp Function .Fn gelf_update_symshndx updates the underlying symbol table entry in data descriptor .Ar symdata with the information in argument .Ar sym . In addition it sets the extended section index in data buffer .Ar xndxdata to the value of argument .Ar xndx . .Sh RETURN VALUES Function .Fn gelf_getsymshndx returns the value of argument .Ar sym if successful, or NULL in case of an error. .Pp Function .Fn gelf_update_symshndx returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar symdata , .Ar xndxdata , .Ar xndxptr or .Ar sym were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero, or too large for either of descriptors .Ar symdata or .Ar xndxdata . .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar symdata was not associated with a section of type .Dv SHT_SYMTAB . .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar xndxdata was not associated with a section of type .Dv SHT_SYMTAB_SHNDX . .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar symdata and .Ar xndxdata were associated with different ELF objects. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 , .Xr gelf_getsym 3 , .Xr gelf_update_sym 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_memory.c0000644000000000000000000000527110525402563016606 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" Elf * elf_memory(char *image, size_t sz) { Elf *e; if (LIBELF_PRIVATE(version) == EV_NONE) { LIBELF_SET_ERROR(SEQUENCE, 0); return (NULL); } if (image == NULL || sz == 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((e = _libelf_allocate_elf()) == NULL) return (NULL); e->e_cmd = ELF_C_READ; e->e_rawfile = image; e->e_rawsize = sz; #undef LIBELF_IS_ELF #define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ (P)[EI_MAG3] == ELFMAG3) if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { _libelf_init_elf(e, ELF_K_ELF); e->e_class = image[EI_CLASS]; e->e_byteorder = image[EI_DATA]; e->e_version = image[EI_VERSION]; if (e->e_version > EV_CURRENT) { e = _libelf_release_elf(e); LIBELF_SET_ERROR(VERSION, 0); return (NULL); } if ((e->e_byteorder != ELFDATA2LSB && e->e_byteorder != ELFDATA2MSB) || (e->e_class != ELFCLASS32 && e->e_class != ELFCLASS64)) { e = _libelf_release_elf(e); LIBELF_SET_ERROR(HEADER, 0); return (NULL); } } else if (sz >= SARMAG && strncmp(image, ARMAG, (size_t) SARMAG) == 0) { _libelf_init_elf(e, ELF_K_AR); e = _libelf_ar_open(e); } else _libelf_init_elf(e, ELF_K_NONE); return (e); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_move.c0000644000000000000000000000740710541424661016417 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" #if __FreeBSD_version >= 700025 GElf_Move * gelf_getmove(Elf_Data *d, int ndx, GElf_Move *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Move *move32; Elf64_Move *move64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { move32 = (Elf32_Move *) d->d_buf + ndx; dst->m_value = move32->m_value; dst->m_info = (Elf64_Xword) move32->m_info; dst->m_poffset = (Elf64_Xword) move32->m_poffset; dst->m_repeat = move32->m_repeat; dst->m_stride = move32->m_stride; } else { move64 = (Elf64_Move *) d->d_buf + ndx; *dst = *move64; } return (dst); } int gelf_update_move(Elf_Data *d, int ndx, GElf_Move *gm) { int ec; Elf *e; Elf_Scn *scn; Elf32_Move *move32; Elf64_Move *move64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || gm == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { move32 = (Elf32_Move *) d->d_buf + ndx; move32->m_value = gm->m_value; LIBELF_COPY_U32(move32, gm, m_info); LIBELF_COPY_U32(move32, gm, m_poffset); move32->m_repeat = gm->m_repeat; move32->m_stride = gm->m_stride; } else { move64 = (Elf64_Move *) d->d_buf + ndx; *move64 = *gm; } return (1); } #endif /* __FreeBSD_version >= 700025 */ freebsd-libs-10.1~svn273304/lib/libelf/_libelf.h0000644000000000000000000001504111421567012016042 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #ifndef __LIBELF_H_ #define __LIBELF_H_ #include #ifndef NULL #define NULL ((void *) 0) #endif /* * Library-private data structures. */ #define LIBELF_MSG_SIZE 256 struct _libelf_globals { int libelf_arch; unsigned int libelf_byteorder; int libelf_class; int libelf_error; int libelf_fillchar; unsigned int libelf_version; char libelf_msg[LIBELF_MSG_SIZE]; }; extern struct _libelf_globals _libelf; #define LIBELF_PRIVATE(N) (_libelf.libelf_##N) #define LIBELF_ELF_ERROR_MASK 0xFF #define LIBELF_OS_ERROR_SHIFT 8 #define LIBELF_SET_ERROR(E, O) do { \ LIBELF_PRIVATE(error) = ((ELF_E_##E & LIBELF_ELF_ERROR_MASK)| \ ((O) << LIBELF_OS_ERROR_SHIFT)); \ } while (0) #define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) /* * Flags for library internal use. These use the upper 16 bits of a * flags field. */ #define LIBELF_F_MALLOCED 0x010000 /* whether data was malloc'ed */ #define LIBELF_F_MMAP 0x020000 /* whether e_rawfile was mmap'ed */ #define LIBELF_F_SHDRS_LOADED 0x040000 /* whether all shdrs were read in */ struct _Elf { int e_activations; /* activation count */ Elf_Arhdr *e_arhdr; /* header for archive members */ unsigned int e_byteorder; /* ELFDATA* */ int e_class; /* ELFCLASS* */ Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ int e_fd; /* associated file descriptor */ unsigned int e_flags; /* ELF_F_*, LIBELF_F_* flags */ Elf_Kind e_kind; /* ELF_K_* */ Elf *e_parent; /* non-NULL for archive members */ char *e_rawfile; /* uninterpreted bytes */ size_t e_rawsize; /* size of uninterpreted bytes */ unsigned int e_version; /* file version */ union { struct { /* ar(1) archives */ off_t e_next; /* set by elf_rand()/elf_next() */ int e_nchildren; char *e_rawstrtab; /* file name strings */ size_t e_rawstrtabsz; char *e_rawsymtab; /* symbol table */ size_t e_rawsymtabsz; Elf_Arsym *e_symtab; size_t e_symtabsz; } e_ar; struct { /* regular ELF files */ union { Elf32_Ehdr *e_ehdr32; Elf64_Ehdr *e_ehdr64; } e_ehdr; union { Elf32_Phdr *e_phdr32; Elf64_Phdr *e_phdr64; } e_phdr; STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ size_t e_nphdr; /* number of Phdr entries */ size_t e_nscn; /* number of sections */ size_t e_strndx; /* string table section index */ } e_elf; } e_u; }; struct _Elf_Scn { union { Elf32_Shdr s_shdr32; Elf64_Shdr s_shdr64; } s_shdr; STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */ STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */ STAILQ_ENTRY(_Elf_Scn) s_next; struct _Elf *s_elf; /* parent ELF descriptor */ unsigned int s_flags; /* flags for the section as a whole */ size_t s_ndx; /* index# for this section */ uint64_t s_offset; /* managed by elf_update() */ uint64_t s_rawoff; /* original offset in the file */ uint64_t s_size; /* managed by elf_update() */ }; enum { ELF_TOFILE, ELF_TOMEMORY }; #define LIBELF_COPY_U32(DST,SRC,NAME) do { \ if ((SRC)->NAME > UINT_MAX) { \ LIBELF_SET_ERROR(RANGE, 0); \ return (0); \ } \ (DST)->NAME = (SRC)->NAME; \ } while (0) #define LIBELF_COPY_S32(DST,SRC,NAME) do { \ if ((SRC)->NAME > INT_MAX || \ (SRC)->NAME < INT_MIN) { \ LIBELF_SET_ERROR(RANGE, 0); \ return (0); \ } \ (DST)->NAME = (SRC)->NAME; \ } while (0) /* * Prototypes */ Elf_Data *_libelf_allocate_data(Elf_Scn *_s); Elf *_libelf_allocate_elf(void); Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); Elf *_libelf_ar_open(Elf *_e); Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname); char *_libelf_ar_get_name(char *_buf, size_t _sz, Elf *_e); int _libelf_ar_get_number(char *_buf, size_t _sz, int _base, size_t *_ret); Elf_Arsym *_libelf_ar_process_symtab(Elf *_ar, size_t *_dst); unsigned long _libelf_checksum(Elf *_e, int _elfclass); void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); int _libelf_falign(Elf_Type _t, int _elfclass); size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, size_t count); int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); void *_libelf_getphdr(Elf *_e, int _elfclass); void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); void _libelf_init_elf(Elf *_e, Elf_Kind _kind); int _libelf_load_scn(Elf *e, void *ehdr); int _libelf_malign(Elf_Type _t, int _elfclass); size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); Elf_Data *_libelf_release_data(Elf_Data *_d); Elf *_libelf_release_elf(Elf *_e); Elf_Scn *_libelf_release_scn(Elf_Scn *_s); 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_setshstrndx(Elf *_e, void *_eh, int _elfclass, size_t _shstrndx); Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, unsigned int _encoding, int _elfclass, int _direction); int _libelf_xlate_shtype(uint32_t _sht); #endif /* __LIBELF_H_ */ freebsd-libs-10.1~svn273304/lib/libelf/elf_memory.30000644000000000000000000000665711361411226016532 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 28, 2006 .Dt ELF_MEMORY 3 .Os .Sh NAME .Nm elf_memory .Nd process an ELF or ar(1) archive mapped into memory .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf *" .Fn elf_memory "char *image" "size_t size" .Sh DESCRIPTION Function .Fn elf_memory is used to process an ELF file or .Xr ar 1 archive whose image is present in memory. .Pp Argument .Ar image points to the start of the memory image of the file or archive. Argument .Ar size contains the size in bytes of the memory image. .Pp The ELF descriptor is created for reading (i.e., analogous to the use of .Xr elf_begin 3 with a command argument value of .Dv ELF_C_READ Ns ). .Sh RETURN VALUES Function .Fn elf_memory returns a pointer to a new ELF descriptor if successful, or NULL if an error occurred. .Pp The return value may be queried for the file type using .Xr elf_kind 3 . .Sh EXAMPLES To read parse an elf file, use: .Bd -literal -offset indent int fd; void *p; struct stat sb; Elf *e; \&... if ((fd = open("./elf-file", O_RDONLY)) < 0 || fstat(fd, &sb) < 0 || (p = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == MAP_FAILED) { ... handle system error ... } if ((e = elf_memory(p, sb.st_size)) == NULL) { ... handle elf(3) error ... } \&... use ELF descriptor "e" here ... .Ed .Sh ERRORS Function .Fn elf_memory can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was used for argument .Ar image or the value of argument .Ar sz was zero. .It Bq Er ELF_E_HEADER The header of the ELF object contained an unsupported value in its .Va e_ident[EI_CLASS] field. .It Bq Er ELF_E_HEADER The header of the ELF object contained an unsupported value in its .Va e_ident[EI_DATA] field. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected. .It Bq Er ELF_E_SEQUENCE Function .Fn elf_memory was called before a working version was set using .Xr elf_version 3 . .It Bq Er ELF_E_VERSION The argument .Ar image corresponds to an ELF file with an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_end 3 , .Xr elf_errno 3 , .Xr elf_kind 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf.h0000644000000000000000000001166310573705232015376 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #ifndef _GELF_H_ #define _GELF_H_ #include #include #include typedef Elf64_Addr GElf_Addr; /* Addresses */ typedef Elf64_Half GElf_Half; /* Half words (16 bit) */ typedef Elf64_Off GElf_Off; /* Offsets */ typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */ typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */ typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ typedef Elf64_Phdr GElf_Phdr; /* Program header */ typedef Elf64_Shdr GElf_Shdr; /* Section header */ typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ typedef Elf64_Rel GElf_Rel; /* Relocation entries */ typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */ #if __FreeBSD_version >= 700025 typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */ typedef Elf64_Move GElf_Move; /* Move entries */ typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */ #endif #define GELF_M_INFO ELF64_M_INFO #define GELF_M_SIZE ELF64_M_SIZE #define GELF_M_SYM ELF64_M_SYM #define GELF_R_INFO ELF64_R_INFO #define GELF_R_SYM ELF64_R_SYM #define GELF_R_TYPE ELF64_R_TYPE #define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA #define GELF_R_TYPE_ID ELF64_R_TYPE_ID #define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO #define GELF_ST_BIND ELF64_ST_BIND #define GELF_ST_INFO ELF64_ST_INFO #define GELF_ST_TYPE ELF64_ST_TYPE #define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY __BEGIN_DECLS long gelf_checksum(Elf *_elf); size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, unsigned int _version); int gelf_getclass(Elf *_elf); GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst); GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst); GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst); GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc, int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst); void * gelf_newehdr(Elf *_elf, int _class); void * gelf_newphdr(Elf *_elf, size_t _phnum); int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src); int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src); int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src); int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src); int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src); int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src); int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src); int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst, int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc); Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); #if __FreeBSD_version >= 700025 GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap); GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst); GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst); int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src); int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src); int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src); #endif __END_DECLS #endif /* _GELF_H_ */ freebsd-libs-10.1~svn273304/lib/libelf/gelf_xlatetof.30000644000000000000000000001527611361411226017214 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd July 24, 2006 .Dt GELF_XLATETOF 3 .Os .Sh NAME .Nm elf32_xlate , .Nm elf64_xlate , .Nm gelf_xlate .Nd translate data between files and memory .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf_Data *" .Fn elf32_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" .Ft "Elf_Data *" .Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" .Ft "Elf_Data *" .Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" .Ft "Elf_Data *" .Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" .In gelf.h .Ft "Elf_Data *" .Fo gelf_xlatetof .Fa "Elf *elf" .Fa "Elf_Data *dst" .Fa "Elf_Data *src" .Fa "unsigned int encode" .Fc .Ft "Elf_Data *" .Fo gelf_xlatetom .Fa "Elf *elf" .Fa "Elf_Data *dst" .Fa "Elf_Data *src" .Fa "unsigned int encode" .Fc .Sh DESCRIPTION These functions translate between the file and memory representations of ELF data structures. The in-memory representation of an ELF data structure would confirm to the byte ordering and data alignment restrictions dictated by the host processor. A file representation of the same data structure could use a non-native byte ordering and in addition may be laid out differently with the file. .Pp Functions .Fn elf32_xlatetom , .Fn elf64_xlatetom , and .Fn gelf_xlatetom translate data from file representations to native, in-memory representations. Functions .Fn elf32_xlatetof , .Fn elf64_xlatetof , and .Fn gelf_xlatetof translate data from in-memory representations to file representations. .Pp Argument .Ar src denotes an .Vt Elf_Data descriptor describing the source to be translated. The following elements of the descriptor need to be set before invoking these functions: .Bl -hang -offset indent .It Va d_buf Set to a valid pointer value denoting the beginning of the data area to be translated. .It Va d_size Set to the total size in bytes of the source data area to be translated. .It Va d_type Set to the type of the source data being translated. This value is one of the values defined in the .Vt Elf_Type enumeration. The .Vt Elf_Type enumeration is described in .Xr elf 3 . .It Va d_version Set to the version number of the ELF data structures being translated. Currently only version .Dv EV_CURRENT is supported. .El .Pp Argument .Ar dst describes the destination buffer. The following elements of the .Vt Elf_Data descriptor need to be set before invoking these functions: .Bl -hang -offset indent .It Va d_buf Set to a valid pointer value that denotes the start of the destination buffer that will hold translated data. This value may be the same as that of the source buffer, in which case an in-place conversion will be attempted. .It Va d_size Set to the size of the destination buffer in bytes. This value will be modified if the function call succeeds. .It Va d_version Set to the desired version number of the destination. Currently only version .Dv EV_CURRENT is supported. .El .Pp These translations routines allow the source and destination buffers to coincide, in which case an in-place translation will be done if the destination is large enough to hold the translated data. Other kinds of overlap between the source and destination buffers are not permitted. .Pp On successful completion of the translation request the following fields of the .Ar dst descriptor would be modified: .Bl -hang -offset indent .It Va d_size Set to the size in bytes of the translated data. .It Va d_type Set to the .Va d_type value of the source data descriptor. .El .Pp Argument .Ar encode specifies the encoding in which the file objects are represented. It must be one of: .Bl -hang -offset indent .It Dv ELFDATANONE File objects use the library's native byte ordering. .It Dv ELFDATA2LSB File objects use a little-endian ordering. .It Dv ELFDATA2MSB File objects use a big-endian ordering. .El .Pp The functions .Fn gelf_xlatetof and .Fn gelf_xlatetom select the appropriate 32 or 64 bit translations based on the class of argument .Ar elf . .Sh RETURN VALUES These functions return argument .Ar dst if successful, or NULL in case of an error. .Sh EXAMPLES TODO .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT One of arguments .Ar src , .Ar dst or .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Arguments .Ar src and .Ar dst were equal. .It Bq Er ELF_E_ARGUMENT The desired encoding parameter was not one of .Dv ELFDATANONE , .Dv ELFDATA2LSB or .Dv ELFDATA2MSB . .It Bq Er ELF_E_ARGUMENT The .Ar d_type field of argument .Ar src specified an unsupported type. .It Bq Er ELF_E_DATA The .Ar src argument specified a buffer size that was not an integral multiple of its underlying type. .It Bq Er ELF_E_DATA The .Ar dst argument specified a buffer size that was too small. .It Bq Er ELF_E_DATA Argument .Ar dst specified a destination buffer that overlaps with the source buffer. .It Bq Er ELF_E_DATA The destination buffer for a conversion to memory had an alignment inappropriate for the underlying ELF type. .It Bq Er ELF_E_DATA The source buffer for a conversion to file had an alignment inappropriate for the underlying ELF type. .It Bq Er ELF_E_UNIMPL The version numbers for arguments .Ar dst and .Ar src were not identical. .It Bq Er ELF_E_UNIMPL The argument .Ar src requested conversion for a type which is not currently supported. .It Bq Er ELF_E_VERSION Argument .Ar src specified an unsupported version number. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_phdr.c0000644000000000000000000001040011421533314016363 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" Elf32_Phdr * elf32_getphdr(Elf *e) { return (_libelf_getphdr(e, ELFCLASS32)); } Elf64_Phdr * elf64_getphdr(Elf *e) { return (_libelf_getphdr(e, ELFCLASS64)); } GElf_Phdr * gelf_getphdr(Elf *e, int index, GElf_Phdr *d) { int ec; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; Elf32_Phdr *ep32; Elf64_Phdr *ep64; if (d == NULL || e == NULL || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || (e->e_kind != ELF_K_ELF) || index < 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL || ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) return (NULL); if (index >= eh32->e_phnum) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ep32 += index; d->p_type = ep32->p_type; d->p_offset = ep32->p_offset; d->p_vaddr = (Elf64_Addr) ep32->p_vaddr; d->p_paddr = (Elf64_Addr) ep32->p_paddr; d->p_filesz = (Elf64_Xword) ep32->p_filesz; d->p_memsz = (Elf64_Xword) ep32->p_memsz; d->p_flags = ep32->p_flags; d->p_align = (Elf64_Xword) ep32->p_align; } else { if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL || (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) return (NULL); if (index >= eh64->e_phnum) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ep64 += index; *d = *ep64; } return (d); } Elf32_Phdr * elf32_newphdr(Elf *e, size_t count) { return (_libelf_newphdr(e, ELFCLASS32, count)); } Elf64_Phdr * elf64_newphdr(Elf *e, size_t count) { return (_libelf_newphdr(e, ELFCLASS64, count)); } void * gelf_newphdr(Elf *e, size_t count) { if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } return (_libelf_newphdr(e, e->e_class, count)); } int gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) { int ec, phnum; void *ehdr; Elf32_Phdr *ph32; Elf64_Phdr *ph64; if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (e->e_cmd == ELF_C_READ) { LIBELF_SET_ERROR(MODE, 0); return (0); } if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (0); if (ec == ELFCLASS32) phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; else phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; if (ndx < 0 || ndx > phnum) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); if (ec == ELFCLASS64) { ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx; *ph64 = *s; return (1); } ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx; ph32->p_type = s->p_type; ph32->p_flags = s->p_flags; LIBELF_COPY_U32(ph32, s, p_offset); LIBELF_COPY_U32(ph32, s, p_vaddr); LIBELF_COPY_U32(ph32, s, p_paddr); LIBELF_COPY_U32(ph32, s, p_filesz); LIBELF_COPY_U32(ph32, s, p_memsz); LIBELF_COPY_U32(ph32, s, p_align); return (1); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_getcap.30000644000000000000000000000656411361411226016631 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETCAP 3 .Os .Sh NAME .Nm gelf_getcap , .Nm gelf_update_cap .Nd read and update ELF capability information .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Cap *" .Fn gelf_getcap "Elf_Data *data" "int ndx" "GElf_Cap *cap" .Ft int .Fn gelf_update_cap "Elf_Data *data" "int ndx" "GElf_Cap *cap" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Cap or .Vt Elf64_Cap information. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_SUNW_cap . Argument .Ar ndx is the index of the entry being retrieved or updated. The class-independent .Vt GElf_Cap structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getcap retrieves the class-dependent entry at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar cap after translation to class-independent form. .Pp Function .Fn gelf_update_cap converts the class-independent entry pointed to by argument .Ar cap to class-dependent form, and writes it to the entry at index .Ar ndx in the data buffer described by argument .Ar data . Function .Fn gelf_update_cap signals an error if any of the values in the class-independent representation exceeds the representable limits of the target type. .Sh RETURN VALUES Function .Fn gelf_getcap returns the value of argument .Ar cap if successful, or NULL in case of an error. Function .Fn gelf_update_cap returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar cap were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of entries in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section of type .Dv SHT_SUNW_cap . .It Bq Er ELF_E_RANGE A value was not representable in the target type. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/libelf.h0000644000000000000000000001675211421562272015720 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #ifndef _LIBELF_H_ #define _LIBELF_H_ #include #include #include #include /* Library private data structures */ typedef struct _Elf Elf; typedef struct _Elf_Scn Elf_Scn; /* File types */ typedef enum { ELF_K_NONE = 0, ELF_K_AR, /* `ar' archives */ ELF_K_COFF, /* COFF files (unsupported) */ ELF_K_ELF, /* ELF files */ ELF_K_NUM } Elf_Kind; #define ELF_K_FIRST ELF_K_NONE #define ELF_K_LAST ELF_K_NUM /* Data types */ typedef enum { ELF_T_ADDR, ELF_T_BYTE, ELF_T_CAP, ELF_T_DYN, ELF_T_EHDR, ELF_T_HALF, ELF_T_LWORD, ELF_T_MOVE, ELF_T_MOVEP, ELF_T_NOTE, ELF_T_OFF, ELF_T_PHDR, ELF_T_REL, ELF_T_RELA, ELF_T_SHDR, ELF_T_SWORD, ELF_T_SXWORD, ELF_T_SYMINFO, ELF_T_SYM, ELF_T_VDEF, ELF_T_VNEED, ELF_T_WORD, ELF_T_XWORD, ELF_T_GNUHASH, /* GNU style hash tables. */ ELF_T_NUM } Elf_Type; #define ELF_T_FIRST ELF_T_ADDR #define ELF_T_LAST ELF_T_GNUHASH /* Commands */ typedef enum { ELF_C_NULL = 0, ELF_C_CLR, ELF_C_FDDONE, ELF_C_FDREAD, ELF_C_RDWR, ELF_C_READ, ELF_C_SET, ELF_C_WRITE, ELF_C_NUM } Elf_Cmd; #define ELF_C_FIRST ELF_C_NULL #define ELF_C_LAST ELF_C_NUM /* * An `Elf_Data' structure describes data in an * ELF section. */ typedef struct _Elf_Data { /* * `Public' members that are part of the ELF(3) API. */ uint64_t d_align; void *d_buf; uint64_t d_off; uint64_t d_size; Elf_Type d_type; unsigned int d_version; /* * Members that are not part of the public API. */ Elf_Scn *d_scn; /* containing section */ unsigned int d_flags; STAILQ_ENTRY(_Elf_Data) d_next; } Elf_Data; /* * An `Elf_Arhdr' structure describes an archive * header. */ typedef struct { time_t ar_date; char *ar_name; /* archive member name */ gid_t ar_gid; mode_t ar_mode; char *ar_rawname; /* 'raw' member name */ size_t ar_size; uid_t ar_uid; } Elf_Arhdr; /* * An `Elf_Arsym' describes an entry in the archive * symbol table. */ typedef struct { off_t as_off; /* byte offset to member's header */ unsigned long as_hash; /* elf_hash() value for name */ char *as_name; /* null terminated symbol name */ } Elf_Arsym; /* * Error numbers. */ enum Elf_Error { ELF_E_NONE, /* No error */ ELF_E_ARCHIVE, /* Malformed ar(1) archive */ ELF_E_ARGUMENT, /* Invalid argument */ ELF_E_CLASS, /* Mismatched ELF class */ ELF_E_DATA, /* Invalid data descriptor */ ELF_E_HEADER, /* Missing or malformed ELF header */ ELF_E_IO, /* I/O error */ ELF_E_LAYOUT, /* Layout constraint violation */ ELF_E_MODE, /* Wrong mode for ELF descriptor */ ELF_E_RANGE, /* Value out of range */ ELF_E_RESOURCE, /* Resource exhaustion */ ELF_E_SECTION, /* Invalid section descriptor */ ELF_E_SEQUENCE, /* API calls out of sequence */ ELF_E_UNIMPL, /* Feature is unimplemented */ ELF_E_VERSION, /* Unknown API version */ ELF_E_NUM /* Max error number */ }; /* * Flags defined by the API. */ #define ELF_F_LAYOUT 0x001U /* application will layout the file */ #define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ __BEGIN_DECLS Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); int elf_cntl(Elf *_elf, Elf_Cmd _cmd); int elf_end(Elf *_elf); const char *elf_errmsg(int _error); int elf_errno(void); void elf_fill(int _fill); unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, unsigned int _flags); unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); Elf_Arhdr *elf_getarhdr(Elf *_elf); Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); off_t elf_getbase(Elf *_elf); Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); char *elf_getident(Elf *_elf, size_t *_ptr); int elf_getphdrnum(Elf *_elf, size_t *_dst); int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ Elf_Scn *elf_getscn(Elf *_elf, size_t _index); int elf_getshdrnum(Elf *_elf, size_t *_dst); int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ int elf_getshdrstrndx(Elf *_elf, size_t *_dst); int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ unsigned long elf_hash(const char *_name); Elf_Kind elf_kind(Elf *_elf); Elf *elf_memory(char *_image, size_t _size); size_t elf_ndxscn(Elf_Scn *_scn); Elf_Data *elf_newdata(Elf_Scn *_scn); Elf_Scn *elf_newscn(Elf *_elf); Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); Elf_Cmd elf_next(Elf *_elf); off_t elf_rand(Elf *_elf, off_t _off); Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); char *elf_rawfile(Elf *_elf, size_t *_size); int elf_setshstrndx(Elf *_elf, size_t _shnum); char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); off_t elf_update(Elf *_elf, Elf_Cmd _cmd); unsigned int elf_version(unsigned int _version); long elf32_checksum(Elf *_elf); size_t elf32_fsize(Elf_Type _type, size_t _count, unsigned int _version); Elf32_Ehdr *elf32_getehdr(Elf *_elf); Elf32_Phdr *elf32_getphdr(Elf *_elf); Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); Elf32_Ehdr *elf32_newehdr(Elf *_elf); Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, unsigned int _enc); Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, unsigned int _enc); long elf64_checksum(Elf *_elf); size_t elf64_fsize(Elf_Type _type, size_t _count, unsigned int _version); Elf64_Ehdr *elf64_getehdr(Elf *_elf); Elf64_Phdr *elf64_getphdr(Elf *_elf); Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); Elf64_Ehdr *elf64_newehdr(Elf *_elf); Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, unsigned int _enc); Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, unsigned int _enc); #if defined(LIBELF_TEST_HOOKS) int _libelf_get_elf_class(Elf *_elf); int _libelf_get_max_error(void); const char *_libelf_get_no_error_message(void); const char *_libelf_get_unknown_error_message(void); void _libelf_set_elf_class(Elf *_elf, int _class); void _libelf_set_error(int _error); #endif /* LIBELF_TEST_HOOKS */ __END_DECLS #endif /* _LIBELF_H_ */ freebsd-libs-10.1~svn273304/lib/libelf/elf_getdata.30000644000000000000000000001347712110570041016623 0ustar .\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd February 18, 2013 .Dt ELF_GETDATA 3 .Os .Sh NAME .Nm elf_getdata , .Nm elf_newdata , .Nm elf_rawdata .Nd iterate through or allocate section data .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf_Data *" .Fn elf_getdata "Elf_Scn *scn" "Elf_Data *data" .Ft "Elf_Data *" .Fn elf_newdata "Elf_Scn *scn" .Ft "Elf_Data *" .Fn elf_rawdata "Elf_Scn *scn" "Elf_Data *data" .Sh DESCRIPTION These functions are used to access and manipulate data descriptors associated with section descriptors. Data descriptors used by the ELF library are described in .Xr elf 3 . .Pp Function .Fn elf_getdata will return the next data descriptor associated with section descriptor .Ar scn . The returned data descriptor will be setup to contain translated data. Argument .Ar data may be NULL, in which case the function returns the first data descriptor associated with section .Ar scn . If argument .Ar data is not NULL, it must be a pointer to a data descriptor associated with section descriptor .Ar scn , and function .Fn elf_getdata will return a pointer to the next data descriptor for the section, or NULL when the end of the section's descriptor list is reached. .Pp Function .Fn elf_newdata will allocate a new data descriptor and append it to the list of data descriptors associated with section descriptor .Ar scn . The new data descriptor will be initialized as follows: .Bl -tag -width "d_version" -compact -offset indent .It Va d_align Set to 1. .It Va d_buf Initialized to NULL. .It Va d_off Set to (off_t) -1. This field is under application control if the .Dv ELF_F_LAYOUT flag was set on the ELF descriptor. .It Va d_size Set to zero. .It Va d_type Initialized to .Dv ELF_T_BYTE . .It Va d_version Set to the current working version of the library, as set by .Xr elf_version 3 . .El The application must set these values as appropriate before calling .Xr elf_update 3 . Section .Ar scn must be associated with an ELF file opened for writing. If the application has not requested full control of layout by setting the .Dv ELF_F_LAYOUT flag on descriptor .Ar elf , then the data referenced by the returned descriptor will be positioned after the existing content of the section, honoring the file alignment specified in member .Va d_align . On successful completion of a call to .Fn elf_newdata , the ELF library will mark the section .Ar scn as .Dq dirty . .Pp Function .Fn elf_rawdata is used to step through the data descriptors associated with section .Ar scn . In contrast to function .Fn elf_getdata , this function returns untranslated data. If argument .Ar data is NULL, the first data descriptor associated with section .Ar scn is returned. If argument .Ar data is not NULL, is must be a data descriptor associated with section .Ar scn , and function .Fn elf_rawdata will return the next data descriptor in the list, or NULL if no further descriptors are present. Function .Fn elf_rawdata always returns .Vt Elf_Data structures of type .Dv ELF_T_BYTE . .Ss Special handling of zero-sized and SHT_NOBITS sections For sections of type .Dv SHT_NOBITS , and for zero-sized sections, the functions .Fn elf_getdata and .Fn elf_rawdata return a pointer to a valid .Vt Elf_Data structure that has its .Va d_buf member set to NULL and its .Va d_size member set to the size of the section. .Pp If an application wishes to create a section of type .Dv SHT_NOBITS , it should add a data buffer to the section using function .Fn elf_newdata . It should then set the .Va d_buf and .Va d_size members of the returned .Vt Elf_Data structure to NULL and the desired size of the section respectively. .Sh RETURN VALUES These functions return a valid pointer to a data descriptor if successful, or NULL if an error occurs. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar scn was NULL. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with section descriptor .Ar scn . .It Bq Er ELF_E_RESOURCE An out of memory condition was detected. .It Bq Er ELF_E_SECTION Section .Ar scn had type .Dv SHT_NULL . .It Bq Er ELF_E_SECTION The type of the section .Ar scn was not recognized by the library. .It Bq Er ELF_E_SECTION The size of the section .Ar scn is not a multiple of the file size for its section type. .It Bq Er ELF_E_SECTION The file offset for section .Ar scn is incorrect. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_flagdata 3 , .Xr elf_flagscn 3 , .Xr elf_getscn 3 , .Xr elf_getshdr 3 , .Xr elf_newscn 3 , .Xr elf_rawfile 3 , .Xr elf_update 3 , .Xr elf_version 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_kind.30000644000000000000000000000422611361411226016135 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 1, 2006 .Dt ELF_KIND 3 .Os .Sh NAME .Nm elf_kind .Nd determine ELF file type .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft Elf_Kind .Fn elf_kind "Elf *elf" .Sh DESCRIPTION The .Fn elf_kind function identifies the kind of file associated with its argument .Ar elf . The argument .Ar elf is allowed to be NULL. .Sh RETURN VALUES The .Fn elf_kind function returns one of the following values: .Bl -tag -width indent .It Dv ELF_K_AR The file associated with argument .Ar elf is an archive. .It Dv ELF_K_ELF The file associated with argument .Ar elf is an ELF file. .It Dv ELF_K_NONE The argument .Ar elf was NULL, or the ELF library could not determine the type of the file associated with argument .Ar elf , or an error occurred when processing. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_getident 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getbase.30000644000000000000000000000437411405134752016633 0ustar .\" Copyright (c) 2006,2008,2010 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 6, 2010 .Dt ELF_GETBASE 3 .Os .Sh NAME .Nm elf_getbase .Nd get the base offset for an object file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft off_t .Fn elf_getbase "Elf *elf" .Sh DESCRIPTION Function .Fn elf_getbase returns the file offset to the first byte of the object referenced by ELF descriptor .Ar elf . .Pp For descriptors referencing members of archives, the returned offset is the file offset of the member in its containing archive. For descriptors to regular objects, the returned offset is (vacuously) zero. .Sh RETURN VALUES Function .Fn elf_getbase returns a valid file offset if successful, or .Pq Vt off_t .Li -1 in case of an error. .Sh ERRORS Function .Fn elf_getbase may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getarhdr 3 , .Xr elf_getident 3 , .Xr elf_rawfile 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_flag.c0000644000000000000000000000743110525402563016207 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" unsigned int elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) { Elf *e; Elf_Scn *scn; unsigned int r; if (d == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL || e->e_kind != ELF_K_ELF || (flags & ~ELF_F_DIRTY) != 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (c == ELF_C_SET) r = scn->s_flags |= flags; else r = scn->s_flags &= ~flags; return (r); } unsigned int elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) { int ec; void *ehdr; if (e == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; else ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; if (ehdr == NULL) { LIBELF_SET_ERROR(SEQUENCE, 0); return (0); } return (elf_flagelf(e, c, flags)); } unsigned int elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) { int r; if (e == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || (e->e_kind != ELF_K_ELF) || (flags & ~(ELF_F_DIRTY|ELF_F_LAYOUT)) != 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (c == ELF_C_SET) r = e->e_flags |= flags; else r = e->e_flags &= ~flags; return (r); } unsigned int elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) { int ec; void *phdr; if (e == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) phdr = e->e_u.e_elf.e_phdr.e_phdr32; else phdr = e->e_u.e_elf.e_phdr.e_phdr64; if (phdr == NULL) { LIBELF_SET_ERROR(SEQUENCE, 0); return (0); } return (elf_flagelf(e, c, flags)); } unsigned int elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) { int r; if (s == NULL) return (0); if ((c != ELF_C_SET && c != ELF_C_CLR) || (flags & ~ELF_F_DIRTY) != 0) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (c == ELF_C_SET) r = s->s_flags |= flags; else r = s->s_flags &= ~flags; return (r); } unsigned int elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) { return (elf_flagscn(s, c, flags)); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_symshndx.c0000644000000000000000000000642510525402563017324 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" GElf_Sym * gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, Elf32_Word *shindex) { int ec; Elf *e; Elf_Scn *scn; size_t msz; uint32_t sh_type; if (gelf_getsym(d, ndx, dst) == 0) return (NULL); if (id == NULL || (scn = id->d_scn) == NULL || (e = scn->s_elf) == NULL || (e != d->d_scn->s_elf) || shindex == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || id->d_type != ELF_T_WORD) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); assert(msz > 0); if (msz * ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } *shindex = ((Elf32_Word *) id->d_buf)[ndx]; return (dst); } int gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, Elf32_Word xindex) { int ec; Elf *e; Elf_Scn *scn; size_t msz; uint32_t sh_type; if (gelf_update_sym(d, ndx, gs) == 0) return (0); if (id == NULL || (scn = id->d_scn) == NULL || (e = scn->s_elf) == NULL || (e != d->d_scn->s_elf)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || d->d_type != ELF_T_WORD) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); assert(msz > 0); if (msz * ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } *(((Elf32_Word *) id->d_buf) + ndx) = xindex; return (1); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_xlate.c0000644000000000000000000000503710525402563016562 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" Elf_Data * elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE); } Elf_Data * elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOFILE); } Elf_Data * elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOMEMORY); } Elf_Data * elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOMEMORY); } Elf_Data * gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { if (e != NULL) return (_libelf_xlate(dst, src, encoding, e->e_class, ELF_TOMEMORY)); LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } Elf_Data * gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { if (e != NULL) return (_libelf_xlate(dst, src, encoding, e->e_class, ELF_TOFILE)); LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_getsym.30000644000000000000000000000677011361411226016675 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETSYM 3 .Os .Sh NAME .Nm gelf_getsym , .Nm gelf_update_sym .Nd read and update symbol information .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Sym *" .Fn gelf_getsym "Elf_Data *data" "int ndx" "GElf_Sym *sym" .Ft int .Fn gelf_update_sym "Elf_Data *data" "int ndx" "GElf_Sym *sym" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Sym and .Vt Elf64_Sym structures in an ELF object. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_SYMTAB , .Dv SHT_DYNSYM or .Dv SHT_GNU_versym . Argument .Ar ndx is the index of the symbol being retrieved or updated. The class-independent .Vt GElf_Sym structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getsym retrieves class-dependent symbol information at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar sym after translation to class-independent form. .Pp Function .Fn gelf_update_sym converts the class-independent symbol information pointed to by argument .Ar sym to class-dependent form, and writes it to the symbol entry at index .Ar ndx in the data buffer described by argument .Ar data . Function .Fn gelf_update_sym signals an error if any of the values in the class-independent representation exceeds the representable limits of the target type. .Sh RETURN VALUES Function .Fn gelf_getsym returns the value of argument .Ar sym if successful, or NULL in case of an error. Function .Fn gelf_update_sym returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar sym were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of symbols in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section containing symbol information. .It Bq Er ELF_E_RANGE A value was not representable in the target type. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 , .Xr gelf_getsyminfo 3 , .Xr gelf_update_syminfo 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_next.c0000644000000000000000000000402610525402563016251 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" Elf_Cmd elf_next(Elf *e) { off_t next; Elf *parent; if (e == NULL) return (ELF_C_NULL); if ((parent = e->e_parent) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (ELF_C_NULL); } assert (parent->e_kind == ELF_K_AR); assert (parent->e_cmd == ELF_C_READ); assert((uintptr_t) e->e_rawfile % 2 == 0); assert(e->e_rawfile > parent->e_rawfile); next = e->e_rawfile - parent->e_rawfile + e->e_rawsize; next = (next + 1) & ~1; /* round up to an even boundary */ parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? (off_t) 0 : next; return (ELF_C_READ); } freebsd-libs-10.1~svn273304/lib/libelf/elf_fill.30000644000000000000000000000362311361411226016136 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 11, 2006 .Dt ELF_FILL 3 .Os .Sh NAME .Nm elf_fill .Nd set fill byte for inter-section padding .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft void .Fn elf_fill "int fill" .Sh DESCRIPTION Function .Fn elf_fill allows an application to specify a fill value for the padding inserted between two sections of an ELF file to meet section alignment constraints. By default the ELF library uses zero bytes for padding. .Pp The ELF library will only pad bytes if the .Dv ELF_F_LAYOUT flag is not set for the ELF file. .Sh SEE ALSO .Xr elf 3 , .Xr elf_flagelf 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_sym.c0000644000000000000000000000740010525402563016251 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" GElf_Sym * gelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Sym *sym32; Elf64_Sym *sym64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { sym32 = (Elf32_Sym *) d->d_buf + ndx; dst->st_name = sym32->st_name; dst->st_value = (Elf64_Addr) sym32->st_value; dst->st_size = (Elf64_Xword) sym32->st_size; dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), ELF32_ST_TYPE(sym32->st_info)); dst->st_other = sym32->st_other; dst->st_shndx = sym32->st_shndx; } else { sym64 = (Elf64_Sym *) d->d_buf + ndx; *dst = *sym64; } return (dst); } int gelf_update_sym(Elf_Data *d, int ndx, GElf_Sym *gs) { int ec; Elf *e; Elf_Scn *scn; Elf32_Sym *sym32; Elf64_Sym *sym64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || gs == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { sym32 = (Elf32_Sym *) d->d_buf + ndx; sym32->st_name = gs->st_name; sym32->st_info = gs->st_info; sym32->st_other = gs->st_other; sym32->st_shndx = gs->st_shndx; LIBELF_COPY_U32(sym32, gs, st_value); LIBELF_COPY_U32(sym32, gs, st_size); } else { sym64 = (Elf64_Sym *) d->d_buf + ndx; *sym64 = *gs; } return (1); } freebsd-libs-10.1~svn273304/lib/libelf/elf_next.30000644000000000000000000000523611361411226016170 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 17, 2006 .Dt ELF_NEXT 3 .Os .Sh NAME .Nm elf_next .Nd provide sequential access to the next archive member .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft Elf_Cmd .Fn elf_next "Elf *elf" .Sh DESCRIPTION The .Fn elf_next function causes the ELF archive descriptor corresponding to argument .Ar elf to be adjusted to provide access to the next member in the archive on a subsequent call to .Fn elf_begin . .Pp The return value of .Fn elf_next is suitable for use in a loop invoking .Fn elf_begin . .Sh RETURN VALUES If successful, function .Fn elf_next returns the value .Dv ELF_C_READ . Otherwise, if argument .Ar elf was not associated with an archive, or if it was .Dv NULL , or if any other error occurred, the value .Dv ELF_C_NULL is returned. .Sh EXAMPLES To process all the members of an archive use: .Bd -literal -offset indent Elf_Cmd cmd; Elf *archive, *e; \&... cmd = ELF_C_READ; archive = elf_begin(fd, cmd, NULL); while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) { ... process `e' here ... cmd = elf_next(e); elf_end(e); } elf_end(archive); .Ed .Sh ERRORS Function .Fn elf_next may fail with the following error: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not associated with a containing .Xr ar 1 archive. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_end 3 , .Xr elf_rand 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_fill.c0000644000000000000000000000274310525402563016225 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" void elf_fill(int fill) { LIBELF_PRIVATE(fillchar) = fill; } freebsd-libs-10.1~svn273304/lib/libelf/elf_kind.c0000644000000000000000000000312110525402563016213 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" Elf_Kind elf_kind(Elf *e) { if (e == NULL) return (ELF_K_NONE); if (e->e_kind == ELF_K_AR || e->e_kind == ELF_K_ELF) return (e->e_kind); return (ELF_K_NONE); } freebsd-libs-10.1~svn273304/lib/libelf/elf_getbase.c0000644000000000000000000000323211405134752016703 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" off_t elf_getbase(Elf *e) { if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return ((off_t) -1); } if (e->e_parent == NULL) return ((off_t) 0); return ((off_t) ((uintptr_t) e->e_rawfile - (uintptr_t) e->e_parent->e_rawfile)); } freebsd-libs-10.1~svn273304/lib/libelf/libelf_shdr.c0000644000000000000000000000341110525402563016717 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" void * _libelf_getshdr(Elf_Scn *s, int ec) { Elf *e; if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASSNONE) ec = e->e_class; if (ec != e->e_class) { LIBELF_SET_ERROR(CLASS, 0); return (NULL); } return ((void *) &s->s_shdr); } freebsd-libs-10.1~svn273304/lib/libelf/elf_version.c0000644000000000000000000000330710525402563016761 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" unsigned int elf_version(unsigned int v) { unsigned int old; if ((old = LIBELF_PRIVATE(version)) == EV_NONE) old = EV_CURRENT; if (v == EV_NONE) return old; if (v > EV_CURRENT) { LIBELF_SET_ERROR(VERSION, 0); return EV_NONE; } LIBELF_PRIVATE(version) = v; return (old); } freebsd-libs-10.1~svn273304/lib/libelf/elf_update.c0000644000000000000000000005607212112427246016564 0ustar /*- * Copyright (c) 2006-2008 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include "_libelf.h" /* * Layout strategy: * * - Case 1: ELF_F_LAYOUT is asserted * In this case the application has full control over where the * section header table, program header table, and section data * will reside. The library only perform error checks. * * - Case 2: ELF_F_LAYOUT is not asserted * * The library will do the object layout using the following * ordering: * - The executable header is placed first, are required by the * ELF specification. * - The program header table is placed immediately following the * executable header. * - Section data, if any, is placed after the program header * table, aligned appropriately. * - The section header table, if needed, is placed last. * * There are two sub-cases to be taken care of: * * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR * * In this sub-case, the underlying ELF object may already have * content in it, which the application may have modified. The * library will retrieve content from the existing object as * needed. * * - Case 2b: e->e_cmd == ELF_C_WRITE * * The ELF object is being created afresh in this sub-case; * there is no pre-existing content in the underlying ELF * object. */ /* * Compute the extents of a section, by looking at the data * descriptors associated with it. The function returns 1 if * successful, or zero if an error was detected. */ static int _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) { int ec; size_t fsz, msz; Elf_Data *d; Elf32_Shdr *shdr32; Elf64_Shdr *shdr64; unsigned int elftype; uint32_t sh_type; uint64_t d_align; uint64_t sh_align, sh_entsize, sh_offset, sh_size; uint64_t scn_size, scn_alignment; ec = e->e_class; shdr32 = &s->s_shdr.s_shdr32; shdr64 = &s->s_shdr.s_shdr64; if (ec == ELFCLASS32) { sh_type = shdr32->sh_type; sh_align = (uint64_t) shdr32->sh_addralign; sh_entsize = (uint64_t) shdr32->sh_entsize; sh_offset = (uint64_t) shdr32->sh_offset; sh_size = (uint64_t) shdr32->sh_size; } else { sh_type = shdr64->sh_type; sh_align = shdr64->sh_addralign; sh_entsize = shdr64->sh_entsize; sh_offset = shdr64->sh_offset; sh_size = shdr64->sh_size; } assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); elftype = _libelf_xlate_shtype(sh_type); if (elftype > ELF_T_LAST) { LIBELF_SET_ERROR(SECTION, 0); return (0); } if (sh_align == 0) sh_align = _libelf_falign(elftype, ec); /* * Check the section's data buffers for sanity and compute the * section's alignment. * Compute the section's size and alignment using the data * descriptors associated with the section. */ if (STAILQ_EMPTY(&s->s_data)) { /* * The section's content (if any) has not been read in * yet. If section is not dirty marked dirty, we can * reuse the values in the 'sh_size' and 'sh_offset' * fields of the section header. */ if ((s->s_flags & ELF_F_DIRTY) == 0) { /* * If the library is doing the layout, then we * compute the new start offset for the * section based on the current offset and the * section's alignment needs. * * If the application is doing the layout, we * can use the value in the 'sh_offset' field * in the section header directly. */ if (e->e_flags & ELF_F_LAYOUT) goto updatedescriptor; else goto computeoffset; } /* * Otherwise, we need to bring in the section's data * from the underlying ELF object. */ if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) return (0); } /* * Loop through the section's data descriptors. */ scn_size = 0L; scn_alignment = 0L; STAILQ_FOREACH(d, &s->s_data, d_next) { if (d->d_type > ELF_T_LAST) { LIBELF_SET_ERROR(DATA, 0); return (0); } if (d->d_version != e->e_version) { LIBELF_SET_ERROR(VERSION, 0); return (0); } if ((d_align = d->d_align) == 0 || (d_align & (d_align - 1))) { LIBELF_SET_ERROR(DATA, 0); return (0); } /* * The buffer's size should be a multiple of the * memory size of the underlying type. */ msz = _libelf_msize(d->d_type, ec, e->e_version); if (d->d_size % msz) { LIBELF_SET_ERROR(DATA, 0); return (0); } /* * Compute the section's size. */ if (e->e_flags & ELF_F_LAYOUT) { if ((uint64_t) d->d_off + d->d_size > scn_size) scn_size = d->d_off + d->d_size; } else { scn_size = roundup2(scn_size, d->d_align); d->d_off = scn_size; fsz = _libelf_fsize(d->d_type, ec, d->d_version, d->d_size / msz); scn_size += fsz; } /* * The section's alignment is the maximum alignment * needed for its data buffers. */ if (d_align > scn_alignment) scn_alignment = d_align; } /* * If the application is requesting full control over the layout * of the section, check its values for sanity. */ if (e->e_flags & ELF_F_LAYOUT) { if (scn_alignment > sh_align || sh_offset % sh_align || sh_size < scn_size) { LIBELF_SET_ERROR(LAYOUT, 0); return (0); } goto updatedescriptor; } /* * Otherwise compute the values in the section header. * * The section alignment is the maximum alignment for any of * its contained data descriptors. */ if (scn_alignment > sh_align) sh_align = scn_alignment; /* * If the section entry size is zero, try and fill in an * appropriate entry size. Per the elf(5) manual page * sections without fixed-size entries should have their * 'sh_entsize' field set to zero. */ if (sh_entsize == 0 && (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, (size_t) 1)) == 1) sh_entsize = 0; sh_size = scn_size; computeoffset: /* * Compute the new offset for the section based on * the section's alignment needs. */ sh_offset = roundup(rc, sh_align); /* * Update the section header. */ if (ec == ELFCLASS32) { shdr32->sh_addralign = (uint32_t) sh_align; shdr32->sh_entsize = (uint32_t) sh_entsize; shdr32->sh_offset = (uint32_t) sh_offset; shdr32->sh_size = (uint32_t) sh_size; } else { shdr64->sh_addralign = sh_align; shdr64->sh_entsize = sh_entsize; shdr64->sh_offset = sh_offset; shdr64->sh_size = sh_size; } updatedescriptor: /* * Update the section descriptor. */ s->s_size = sh_size; s->s_offset = sh_offset; return (1); } /* * Insert a section in ascending order in the list */ static int _libelf_insert_section(Elf *e, Elf_Scn *s) { Elf_Scn *t, *prevt; uint64_t smax, smin, tmax, tmin; smin = s->s_offset; smax = smin + s->s_size; prevt = NULL; STAILQ_FOREACH(t, &e->e_u.e_elf.e_scn, s_next) { tmin = t->s_offset; tmax = tmin + t->s_size; if (tmax <= smin) { /* * 't' lies entirely before 's': ...| t |...| s |... */ prevt = t; continue; } else if (smax <= tmin) /* * 's' lies entirely before 't', and after 'prevt': * ...| prevt |...| s |...| t |... */ break; else { /* 's' and 't' overlap. */ LIBELF_SET_ERROR(LAYOUT, 0); return (0); } } if (prevt) STAILQ_INSERT_AFTER(&e->e_u.e_elf.e_scn, prevt, s, s_next); else STAILQ_INSERT_HEAD(&e->e_u.e_elf.e_scn, s, s_next); return (1); } /* * Recompute section layout. */ static off_t _libelf_resync_sections(Elf *e, off_t rc) { int ec; Elf_Scn *s; size_t sh_type, shdr_start, shdr_end; ec = e->e_class; /* * Make a pass through sections, computing the extent of each * section. Order in increasing order of addresses. */ STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { if (ec == ELFCLASS32) sh_type = s->s_shdr.s_shdr32.sh_type; else sh_type = s->s_shdr.s_shdr64.sh_type; if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) continue; if (_libelf_compute_section_extents(e, s, rc) == 0) return ((off_t) -1); if (s->s_size == 0) continue; if (s->s_offset + s->s_size < (size_t) rc) { /* * Try insert this section in the * correct place in the list, * detecting overlaps if any. */ STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); if (_libelf_insert_section(e, s) == 0) return ((off_t) -1); } else rc = s->s_offset + s->s_size; } /* * If the application is controlling file layout, check for an * overlap between this section's extents and the SHDR table. */ if (e->e_flags & ELF_F_LAYOUT) { if (e->e_class == ELFCLASS32) shdr_start = e->e_u.e_elf.e_ehdr.e_ehdr32->e_shoff; else shdr_start = e->e_u.e_elf.e_ehdr.e_ehdr64->e_shoff; shdr_end = shdr_start + _libelf_fsize(ELF_T_SHDR, e->e_class, e->e_version, e->e_u.e_elf.e_nscn); STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { if (s->s_offset >= shdr_end || s->s_offset + s->s_size <= shdr_start) continue; LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } return (rc); } static off_t _libelf_resync_elf(Elf *e) { int ec, eh_class, eh_type; unsigned int eh_byteorder, eh_version; size_t align, fsz; size_t phnum, shnum; off_t rc, phoff, shoff; void *ehdr; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; rc = 0; ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); /* * Prepare the EHDR. */ if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return ((off_t) -1); eh32 = ehdr; eh64 = ehdr; if (ec == ELFCLASS32) { eh_byteorder = eh32->e_ident[EI_DATA]; eh_class = eh32->e_ident[EI_CLASS]; phoff = (uint64_t) eh32->e_phoff; shoff = (uint64_t) eh32->e_shoff; eh_type = eh32->e_type; eh_version = eh32->e_version; } else { eh_byteorder = eh64->e_ident[EI_DATA]; eh_class = eh64->e_ident[EI_CLASS]; phoff = eh64->e_phoff; shoff = eh64->e_shoff; eh_type = eh64->e_type; eh_version = eh64->e_version; } if (eh_version == EV_NONE) eh_version = EV_CURRENT; if (eh_version != e->e_version) { /* always EV_CURRENT */ LIBELF_SET_ERROR(VERSION, 0); return ((off_t) -1); } if (eh_class != e->e_class) { LIBELF_SET_ERROR(CLASS, 0); return ((off_t) -1); } if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { LIBELF_SET_ERROR(HEADER, 0); return ((off_t) -1); } shnum = e->e_u.e_elf.e_nscn; phnum = e->e_u.e_elf.e_nphdr; e->e_byteorder = eh_byteorder; #define INITIALIZE_EHDR(E,EC,V) do { \ (E)->e_ident[EI_MAG0] = ELFMAG0; \ (E)->e_ident[EI_MAG1] = ELFMAG1; \ (E)->e_ident[EI_MAG2] = ELFMAG2; \ (E)->e_ident[EI_MAG3] = ELFMAG3; \ (E)->e_ident[EI_CLASS] = (EC); \ (E)->e_ident[EI_VERSION] = (V); \ (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ (size_t) 1); \ (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ ELF_T_PHDR, (EC), (V), (size_t) 1); \ (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ (size_t) 1); \ } while (0) if (ec == ELFCLASS32) INITIALIZE_EHDR(eh32, ec, eh_version); else INITIALIZE_EHDR(eh64, ec, eh_version); (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); /* * Compute the layout the program header table, if one is * present. The program header table needs to be aligned to a * `natural' boundary. */ if (phnum) { fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); align = _libelf_falign(ELF_T_PHDR, ec); if (e->e_flags & ELF_F_LAYOUT) { /* * Check offsets for sanity. */ if (rc > phoff) { LIBELF_SET_ERROR(HEADER, 0); return ((off_t) -1); } if (phoff % align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else phoff = roundup(rc, align); rc = phoff + fsz; } else phoff = 0; /* * Compute the layout of the sections associated with the * file. */ if (e->e_cmd != ELF_C_WRITE && (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && _libelf_load_scn(e, ehdr) == 0) return ((off_t) -1); if ((rc = _libelf_resync_sections(e, rc)) < 0) return ((off_t) -1); /* * Compute the space taken up by the section header table, if * one is needed. If ELF_F_LAYOUT is asserted, the * application may have placed the section header table in * between existing sections, so the net size of the file need * not increase due to the presence of the section header * table. */ if (shnum) { fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, (size_t) 1); align = _libelf_falign(ELF_T_SHDR, ec); if (e->e_flags & ELF_F_LAYOUT) { if (shoff % align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else shoff = roundup(rc, align); if (shoff + fsz * shnum > (size_t) rc) rc = shoff + fsz * shnum; } else shoff = 0; /* * Set the fields of the Executable Header that could potentially use * extended numbering. */ _libelf_setphnum(e, ehdr, ec, phnum); _libelf_setshnum(e, ehdr, ec, shnum); /* * Update the `e_phoff' and `e_shoff' fields if the library is * doing the layout. */ if ((e->e_flags & ELF_F_LAYOUT) == 0) { if (ec == ELFCLASS32) { eh32->e_phoff = (uint32_t) phoff; eh32->e_shoff = (uint32_t) shoff; } else { eh64->e_phoff = (uint64_t) phoff; eh64->e_shoff = (uint64_t) shoff; } } return (rc); } /* * Write out the contents of a section. */ static off_t _libelf_write_scn(Elf *e, char *nf, Elf_Scn *s, off_t rc) { int ec; size_t fsz, msz, nobjects; uint32_t sh_type; uint64_t sh_off, sh_size; int elftype; Elf_Data *d, dst; if ((ec = e->e_class) == ELFCLASS32) { sh_type = s->s_shdr.s_shdr32.sh_type; sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; } else { sh_type = s->s_shdr.s_shdr64.sh_type; sh_size = s->s_shdr.s_shdr64.sh_size; } /* * Ignore sections that do not allocate space in the file. */ if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) return (rc); elftype = _libelf_xlate_shtype(sh_type); assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); sh_off = s->s_offset; assert(sh_off % _libelf_falign(elftype, ec) == 0); /* * If the section has a `rawdata' descriptor, and the section * contents have not been modified, use its contents directly. * The `s_rawoff' member contains the offset into the original * file, while `s_offset' contains its new location in the * destination. */ if (STAILQ_EMPTY(&s->s_data)) { if ((d = elf_rawdata(s, NULL)) == NULL) return ((off_t) -1); STAILQ_FOREACH(d, &s->s_rawdata, d_next) { if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); rc = sh_off + d->d_off; assert(d->d_buf != NULL); assert(d->d_type == ELF_T_BYTE); assert(d->d_version == e->e_version); (void) memcpy(nf + rc, e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); rc += d->d_size; } return (rc); } /* * Iterate over the set of data descriptors for this section. * The prior call to _libelf_resync_elf() would have setup the * descriptors for this step. */ dst.d_version = e->e_version; STAILQ_FOREACH(d, &s->s_data, d_next) { msz = _libelf_msize(d->d_type, ec, e->e_version); if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); rc = sh_off + d->d_off; assert(d->d_buf != NULL); assert(d->d_version == e->e_version); assert(d->d_size % msz == 0); nobjects = d->d_size / msz; fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); dst.d_buf = nf + rc; dst.d_size = fsz; if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == NULL) return ((off_t) -1); rc += fsz; } return ((off_t) rc); } /* * Write out the file image. * * The original file could have been mapped in with an ELF_C_RDWR * command and the application could have added new content or * re-arranged its sections before calling elf_update(). Consequently * its not safe to work `in place' on the original file. So we * malloc() the required space for the updated ELF object and build * the object there and write it out to the underlying file at the * end. Note that the application may have opened the underlying file * in ELF_C_RDWR and only retrieved/modified a few sections. We take * care to avoid translating file sections unnecessarily. * * Gaps in the coverage of the file by the file's sections will be * filled with the fill character set by elf_fill(3). */ static off_t _libelf_write_elf(Elf *e, off_t newsize) { int ec; off_t maxrc, rc; size_t fsz, msz, phnum, shnum; uint64_t phoff, shoff; void *ehdr; char *newfile; Elf_Data dst, src; Elf_Scn *scn, *tscn; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; assert(e->e_kind == ELF_K_ELF); assert(e->e_cmd != ELF_C_READ); assert(e->e_fd >= 0); if ((newfile = malloc((size_t) newsize)) == NULL) { LIBELF_SET_ERROR(RESOURCE, errno); return ((off_t) -1); } ec = e->e_class; ehdr = _libelf_ehdr(e, ec, 0); assert(ehdr != NULL); phnum = e->e_u.e_elf.e_nphdr; if (ec == ELFCLASS32) { eh32 = (Elf32_Ehdr *) ehdr; phoff = (uint64_t) eh32->e_phoff; shnum = eh32->e_shnum; shoff = (uint64_t) eh32->e_shoff; } else { eh64 = (Elf64_Ehdr *) ehdr; phoff = eh64->e_phoff; shnum = eh64->e_shnum; shoff = eh64->e_shoff; } fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); (void) memset(&dst, 0, sizeof(dst)); (void) memset(&src, 0, sizeof(src)); src.d_buf = ehdr; src.d_size = msz; src.d_type = ELF_T_EHDR; src.d_version = dst.d_version = e->e_version; rc = 0; dst.d_buf = newfile + rc; dst.d_size = fsz; if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == NULL) goto error; rc += fsz; /* * Write the program header table if present. */ if (phnum != 0 && phoff != 0) { assert((unsigned) rc <= phoff); fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); assert(fsz > 0); src.d_buf = _libelf_getphdr(e, ec); src.d_version = dst.d_version = e->e_version; src.d_type = ELF_T_PHDR; src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, e->e_version); dst.d_size = fsz; if ((uint64_t) rc < phoff) (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), phoff - rc); dst.d_buf = newfile + rc; if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == NULL) goto error; rc = phoff + fsz; } /* * Write out individual sections. */ STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) if ((rc = _libelf_write_scn(e, newfile, scn, rc)) < 0) goto error; /* * Write out the section header table, if required. Note that * if flag ELF_F_LAYOUT has been set the section header table * could reside in between byte ranges mapped by section * descriptors. */ if (shnum != 0 && shoff != 0) { if ((uint64_t) rc < shoff) (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), shoff - rc); maxrc = rc; rc = shoff; assert(rc % _libelf_falign(ELF_T_SHDR, ec) == 0); src.d_type = ELF_T_SHDR; src.d_size = _libelf_msize(ELF_T_SHDR, ec, 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); STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { if (ec == ELFCLASS32) src.d_buf = &scn->s_shdr.s_shdr32; else src.d_buf = &scn->s_shdr.s_shdr64; dst.d_size = fsz; dst.d_buf = newfile + rc + scn->s_ndx * fsz; if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) != &dst) goto error; } rc += e->e_u.e_elf.e_nscn * fsz; if (maxrc > rc) rc = maxrc; } assert(rc == newsize); /* * Write out the constructed contents and remap the file in * read-only. */ if (e->e_rawfile && munmap(e->e_rawfile, e->e_rawsize) < 0) { LIBELF_SET_ERROR(IO, errno); goto error; } if (write(e->e_fd, newfile, (size_t) newsize) != newsize || lseek(e->e_fd, (off_t) 0, SEEK_SET) < 0) { LIBELF_SET_ERROR(IO, errno); goto error; } if (e->e_cmd != ELF_C_WRITE) { if ((e->e_rawfile = mmap(NULL, (size_t) newsize, PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) == MAP_FAILED) { LIBELF_SET_ERROR(IO, errno); goto error; } e->e_rawsize = newsize; } /* * Reset flags, remove existing section descriptors and * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() * and elf_getscn() will function correctly. */ e->e_flags &= ~ELF_F_DIRTY; STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) _libelf_release_scn(scn); if (ec == ELFCLASS32) { free(e->e_u.e_elf.e_ehdr.e_ehdr32); if (e->e_u.e_elf.e_phdr.e_phdr32) free(e->e_u.e_elf.e_phdr.e_phdr32); e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; e->e_u.e_elf.e_phdr.e_phdr32 = NULL; } else { free(e->e_u.e_elf.e_ehdr.e_ehdr64); if (e->e_u.e_elf.e_phdr.e_phdr64) free(e->e_u.e_elf.e_phdr.e_phdr64); e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; e->e_u.e_elf.e_phdr.e_phdr64 = NULL; } free(newfile); return (rc); error: free(newfile); return ((off_t) -1); } off_t elf_update(Elf *e, Elf_Cmd c) { int ec; off_t rc; rc = (off_t) -1; if (e == NULL || e->e_kind != ELF_K_ELF || (c != ELF_C_NULL && c != ELF_C_WRITE)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (rc); } if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { LIBELF_SET_ERROR(CLASS, 0); return (rc); } if (e->e_version == EV_NONE) e->e_version = EV_CURRENT; if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { LIBELF_SET_ERROR(MODE, 0); return (rc); } if ((rc = _libelf_resync_elf(e)) < 0) return (rc); if (c == ELF_C_NULL) return (rc); if (e->e_cmd == ELF_C_READ) { /* * This descriptor was opened in read-only mode or by * elf_memory(). */ if (e->e_fd) LIBELF_SET_ERROR(MODE, 0); else LIBELF_SET_ERROR(ARGUMENT, 0); return ((off_t) -1); } if (e->e_fd < 0) { LIBELF_SET_ERROR(SEQUENCE, 0); return ((off_t) -1); } return (_libelf_write_elf(e, rc)); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_update_ehdr.30000644000000000000000000000711711361411226017645 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 27, 2006 .Dt GELF_UPDATE_EHDR 3 .Os .Sh NAME .Nm gelf_update_ehdr , .Nm gelf_update_phdr , .Nm gelf_update_shdr .Nd update underlying ELF data structures .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft int .Fn gelf_update_ehdr "Elf *elf" "GElf_Ehdr *ehdr" .Ft int .Fn gelf_update_phdr "Elf *elf" "int ndx" "GElf_Phdr *phdr" .Ft int .Fn gelf_update_shdr "Elf_Scn *scn" "GElf_Shdr *shdr" .Sh DESCRIPTION These functions are used to update ELF data structures on the underlying ELF descriptor. Class-dependent data structures in the underlying ELF descriptor are updated using the data in the class-independent GElf descriptors and the underlying ELF data structures are marked .Dq dirty . The conversion process signals an error if the values being copied to the target ELF data structure would exceed representation limits. GElf descriptors are described in .Xr gelf 3 . .Pp Function .Fn gelf_update_ehdr updates the ELF Executable Header with the values in the class-independent executable header .Ar ehdr . .Pp Function .Fn gelf_update_phdr updates the ELF Program Header structure at index .Ar ndx with the values in the class-independent program header .Ar phdr . .Pp Function .Fn gelf_update_shdr updates the ELF Section Header structure associated with section descriptor .Ar scn with the values in argument .Ar shdr . .Sh RETURN VALUES These functions return a non-zero integer on success, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar elf , .Ar ehdr , .Ar phdr , .Ar scn , or .Ar shdr were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf had an unsupported ELF class. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx exceeded the number of entries in the program header table. .It Bq Er ELF_E_ARGUMENT Section descriptor .Ar scn was not associated with an ELF descriptor. .It Bq Er ELF_E_MODE ELF descriptor .Ar elf was not opened for writing or updating. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_flagelf 3 , .Xr elf_flagphdr 3 , .Xr elf_flagshdr 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 , .Xr gelf_getphdr 3 , .Xr gelf_getshdr 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getarsym.30000644000000000000000000000713311361411226017043 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 15, 2006 .Dt ELF_GETARSYM 3 .Os .Sh NAME .Nm elf_getarsym .Nd retrieve the symbol table of an archive .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf_Arsym *" .Fn elf_getarsym "Elf *elf" "size_t *ptr" .Sh DESCRIPTION The function .Fn elf_getarsym retrieves the symbol table for an .Xr ar 1 archive, if one is available. .Pp Argument .Ar elf should be a descriptor for an .Xr ar 1 archive opened using .Fn elf_begin or .Fn elf_memory . .Pp If the archive .Ar elf contains a symbol table with n entries, this function returns a pointer to an array of n+1 .Vt Elf_Arsym structures. An .Vt Elf_Arsym structure has the following elements: .Bl -tag -width indent -compact .It Vt "char *" Va as_name This structure member is a pointer to a null-terminated symbol name. .It Vt "off_t" Va as_off This structure member contains the byte offset from the beginning of the archive to the header for the archive member. This value is suitable for use with .Xr elf_rand 3 . .It Vt "unsigned long" Va as_hash This structure member contains a portable hash value for the symbol name, as computed by .Xr elf_hash 3 . .El .Pp The last entry of the returned array will have a NULL value for member .Va as_name , a zero value for member .Va as_off and an illegal value of ~0UL for .Va as_hash . .Pp If argument .Ar ptr is non-null, the .Fn elf_getarsym function will store the number of table entries returned (including the sentinel entry at the end) into the location it points to. .Sh RETURN VALUES Function .Fn elf_getarsym returns a pointer to an array of .Vt Elf_Arsym structures if successful, or a NULL pointer if an error was encountered. .Pp If argument .Ar ptr is non-null and there was no error, the library will store the number of archive symbol entries returned into the location it points to. If argument .Ar ptr is non-null and an error was encountered, the library will set the location pointed to by it to zero. .Sh ERRORS Function .Fn elf_getarsym may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an .Xr ar 1 archive. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_getarhdr 3 , .Xr elf_hash 3 , .Xr elf_memory 3 , .Xr elf_next 3 , .Xr elf_rand 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_shnum.c0000644000000000000000000000372111421562272016426 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" static int _libelf_getshdrnum(Elf *e, size_t *shnum) { void *eh; int ec; if (e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (-1); } if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) return (-1); *shnum = e->e_u.e_elf.e_nscn; return (0); } int elf_getshdrnum(Elf *e, size_t *shnum) { return (_libelf_getshdrnum(e, shnum)); } /* Deprecated API. */ int elf_getshnum(Elf *e, size_t *shnum) { return (_libelf_getshdrnum(e, shnum) >= 0); } freebsd-libs-10.1~svn273304/lib/libelf/libelf_data.c0000644000000000000000000000577012210431100016660 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" int _libelf_xlate_shtype(uint32_t sht) { switch (sht) { case SHT_DYNAMIC: return (ELF_T_DYN); case SHT_DYNSYM: return (ELF_T_SYM); case SHT_FINI_ARRAY: return (ELF_T_ADDR); #if __FreeBSD_version >= 800062 case SHT_GNU_HASH: return (ELF_T_GNUHASH); #endif case SHT_GROUP: return (ELF_T_WORD); case SHT_HASH: return (ELF_T_WORD); case SHT_INIT_ARRAY: return (ELF_T_ADDR); case SHT_NOBITS: return (ELF_T_BYTE); case SHT_NOTE: return (ELF_T_NOTE); case SHT_PREINIT_ARRAY: return (ELF_T_ADDR); case SHT_PROGBITS: return (ELF_T_BYTE); case SHT_REL: return (ELF_T_REL); case SHT_RELA: return (ELF_T_RELA); case SHT_STRTAB: return (ELF_T_BYTE); case SHT_SYMTAB: return (ELF_T_SYM); case SHT_SYMTAB_SHNDX: return (ELF_T_WORD); #if __FreeBSD_version >= 700025 case SHT_GNU_verdef: /* == SHT_SUNW_verdef */ return (ELF_T_VDEF); case SHT_GNU_verneed: /* == SHT_SUNW_verneed */ return (ELF_T_VNEED); case SHT_GNU_versym: /* == SHT_SUNW_versym */ return (ELF_T_HALF); case SHT_SUNW_move: return (ELF_T_MOVE); case SHT_SUNW_syminfo: return (ELF_T_SYMINFO); case SHT_SUNW_dof: return (ELF_T_BYTE); #endif case SHT_ARM_PREEMPTMAP: /* FALLTHROUGH */ case SHT_ARM_ATTRIBUTES: /* FALLTHROUGH */ case SHT_ARM_DEBUGOVERLAY: /* FALLTHROUGH */ case SHT_ARM_OVERLAYSECTION: /* FALLTHROUGH */ case SHT_MIPS_DWARF: /* FALLTHROUGH */ case SHT_MIPS_REGINFO: /* FALLTHROUGH */ case SHT_MIPS_OPTIONS: /* FALLTHROUGH */ case SHT_AMD64_UNWIND: /* == SHT_IA_64_UNWIND == SHT_ARM_EXIDX */ return (ELF_T_BYTE); default: return (-1); } } freebsd-libs-10.1~svn273304/lib/libelf/elf_errno.c0000644000000000000000000000335010525402563016417 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" int elf_errno(void) { int old; old = LIBELF_PRIVATE(error); LIBELF_PRIVATE(error) = 0; return (old & LIBELF_ELF_ERROR_MASK); } #if defined(LIBELF_TEST_HOOKS) int _libelf_get_max_error(void) { return ELF_E_NUM; } void _libelf_set_error(int error) { LIBELF_PRIVATE(error) = error; } #endif /* LIBELF_TEST_HOOKS */ freebsd-libs-10.1~svn273304/lib/libelf/gelf_rela.c0000644000000000000000000000747510762445046016406 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" GElf_Rela * gelf_getrela(Elf_Data *d, int ndx, GElf_Rela *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Rela *rela32; Elf64_Rela *rela64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { rela32 = (Elf32_Rela *) d->d_buf + ndx; dst->r_offset = (Elf64_Addr) rela32->r_offset; dst->r_info = ELF64_R_INFO( (Elf64_Xword) ELF32_R_SYM(rela32->r_info), ELF32_R_TYPE(rela32->r_info)); dst->r_addend = (Elf64_Sxword) rela32->r_addend; } else { rela64 = (Elf64_Rela *) d->d_buf + ndx; *dst = *rela64; } return (dst); } int gelf_update_rela(Elf_Data *d, int ndx, GElf_Rela *dr) { int ec; Elf *e; Elf_Scn *scn; Elf32_Rela *rela32; Elf64_Rela *rela64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dr == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { rela32 = (Elf32_Rela *) d->d_buf + ndx; LIBELF_COPY_U32(rela32, dr, r_offset); if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { LIBELF_SET_ERROR(RANGE, 0); return (0); } rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), ELF64_R_TYPE(dr->r_info)); LIBELF_COPY_S32(rela32, dr, r_addend); } else { rela64 = (Elf64_Rela *) d->d_buf + ndx; *rela64 = *dr; } return (1); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_getshdr.30000644000000000000000000000620411361411226017015 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 27, 2006 .Dt GELF_GETSHDR 3 .Os .Sh NAME .Nm elf32_getshdr , .Nm elf64_getshdr , .Nm gelf_getshdr .Nd retrieve the class-dependent section header .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf32_Shdr *" .Fn elf32_getshdr "Elf_Scn *scn" .Ft "Elf64_Shdr *" .Fn elf64_getshdr "Elf_Scn *scn" .In gelf.h .Ft "GElf_Shdr *" .Fn gelf_getshdr "Elf_Scn *scn" "GElf_Shdr *shdr" .Sh DESCRIPTION These functions return a pointer to the ELF Section Header data structure associated with section descriptor .Ar scn . .Pp Function .Fn elf32_getshdr retrieves a pointer to an .Vt Elf32_Shdr structure. Section descriptor .Ar scn must be associated with an ELF descriptor of class .Dv ELFCLASS32 . .Pp Function .Fn elf64_getshdr retrieves a pointer to an .Vt Elf64_Shdr structure. Section descriptor .Ar scn must be associated with an ELF descriptor of class .Dv ELFCLASS64 . .Pp Function .Fn gelf_getshdr copies the values in the section header associated with argument .Ar scn to the structure pointed to be argument .Ar dst . The .Vt GElf_Shdr data structure is described in .Xr gelf 3 . .Sh RETURN VALUES Functions .Fn elf32_getshdr and .Fn elf64_getshdr return a valid pointer to the appropriate section header on success or NULL if an error was encountered. .Pp Function .Fn gelf_getshdr returns argument .Ar dst if successful, or NULL if an error was encountered. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar scn or .Ar shdr were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar scn was not associated a descriptor for an ELF object. .It Bq Er ELF_E_CLASS The ELF class associated with the section descriptor .Ar scn did not match the class expected by the API. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getscn 3 , .Xr gelf 3 , .Xr gelf_update_shdr 3 freebsd-libs-10.1~svn273304/lib/libelf/Version.map0000644000000000000000000000302611421562272016424 0ustar /* * $FreeBSD$ */ FBSD_1.0 { global: elf32_checksum; elf32_fsize; elf32_getehdr; elf32_getphdr; elf32_getshdr; elf32_newehdr; elf32_newphdr; elf32_xlatetof; elf32_xlatetom; elf64_checksum; elf64_fsize; elf64_getehdr; elf64_getphdr; elf64_getshdr; elf64_newehdr; elf64_newphdr; elf64_xlatetof; elf64_xlatetom; elf_begin; elf_cntl; elf_end; elf_errmsg; elf_errno; elf_fill; elf_flagdata; elf_flagehdr; elf_flagelf; elf_flagphdr; elf_flagscn; elf_flagshdr; elf_getarhdr; elf_getarsym; elf_getbase; elf_getdata; elf_getident; elf_getscn; elf_getphdrnum; elf_getphnum; elf_getshdrnum; elf_getshnum; elf_getshdrstrndx; elf_getshstrndx; elf_hash; elf_kind; elf_memory; elf_ndxscn; elf_newdata; elf_newscn; elf_next; elf_nextscn; elf_rand; elf_rawdata; elf_rawfile; elf_setshstrndx; elf_strptr; elf_update; elf_version; gelf_checksum; gelf_fsize; gelf_getcap; gelf_getclass; gelf_getdyn; gelf_getehdr; gelf_getmove; gelf_getphdr; gelf_getrel; gelf_getrela; gelf_getshdr; gelf_getsym; gelf_getsyminfo; gelf_getsymshndx; gelf_newehdr; gelf_newphdr; gelf_update_cap; gelf_update_dyn; gelf_update_ehdr; gelf_update_move; gelf_update_phdr; gelf_update_rel; gelf_update_rela; gelf_update_shdr; gelf_update_sym; gelf_update_syminfo; gelf_update_symshndx; gelf_xlatetof; gelf_xlatetom; local: *; }; /* * Private symbols, mostly test hooks */ FBSDprivate_1.0 { global: _libelf_set_error; _libelf_get_max_error; _libelf_get_no_error_message; _libelf_get_unknown_error_message; }; freebsd-libs-10.1~svn273304/lib/libelf/libelf_ar.c0000644000000000000000000001610711421567012016364 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include "_libelf.h" #define LIBELF_NALLOC_SIZE 16 /* * `ar' archive handling. * * `ar' archives start with signature `ARMAG'. Each archive member is * preceded by a header containing meta-data for the member. This * header is described in (struct ar_hdr). The header always * starts on an even address. File data is padded with "\n" * characters to keep this invariant. * * Special considerations for `ar' archives: * * The `ar' header only has space for a 16 character file name. File * names are terminated with a '/', so this effectively leaves 15 * characters for the actual file name. In order to accomodate longer * file names, names may be stored in a separate 'string table' and * referenced indirectly by a member header. The string table itself * appears as an archive member with name "// ". An indirect file name * in an `ar' header matches the pattern "/[0-9]*". The digits form a * decimal number that corresponds to a byte offset into the string * table where the actual file name of the object starts. Strings in * the string table are padded to start on even addresses. * * Archives may also have a symbol table (see ranlib(1)), mapping * program symbols to object files inside the archive. A symbol table * uses a file name of "/ " in its archive header. The symbol table * is structured as: * - a 4-byte count of entries stored as a binary value, MSB first * - 'n' 4-byte offsets, stored as binary values, MSB first * - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded. * * If the symbol table and string table are is present in an archive * they must be the very first objects and in that order. */ Elf_Arhdr * _libelf_ar_gethdr(Elf *e) { Elf *parent; struct ar_hdr *arh; Elf_Arhdr *eh; size_t n; if ((parent = e->e_parent) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } arh = (struct ar_hdr *) ((uintptr_t) e->e_rawfile - sizeof(struct ar_hdr)); 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)); if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } e->e_arhdr = eh; eh->ar_name = eh->ar_rawname = NULL; if ((eh->ar_name = _libelf_ar_get_name(arh->ar_name, sizeof(arh->ar_name), parent)) == NULL) goto error; if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10, &n) == 0) goto error; eh->ar_uid = (uid_t) n; if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10, &n) == 0) goto error; eh->ar_gid = (gid_t) n; if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8, &n) == 0) goto error; eh->ar_mode = (mode_t) n; if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, &n) == 0) goto error; eh->ar_size = n; if ((eh->ar_rawname = _libelf_ar_get_string(arh->ar_name, sizeof(arh->ar_name), 1)) == NULL) goto error; return (eh); error: if (eh) { if (eh->ar_name) free(eh->ar_name); if (eh->ar_rawname) free(eh->ar_rawname); free(eh); } e->e_arhdr = NULL; return (NULL); } Elf * _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) { Elf *e; off_t next; struct ar_hdr *arh; size_t sz; assert(elf->e_kind == ELF_K_AR); next = elf->e_u.e_ar.e_next; /* * `next' is only set to zero by elf_next() when the last * member of an archive is processed. */ if (next == (off_t) 0) return (NULL); assert((next & 1) == 0); arh = (struct ar_hdr *) (elf->e_rawfile + next); if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, &sz) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } assert(sz > 0); arh++; /* skip over archive member header */ if ((e = elf_memory((char *) arh, sz)) == NULL) return (NULL); e->e_fd = fd; e->e_cmd = c; elf->e_u.e_ar.e_nchildren++; e->e_parent = elf; return (e); } /* * An ar(1) symbol table has the following layout: * * The first 4 bytes are a binary count of the number of entries in the * symbol table, stored MSB-first. * * Then there are 'n' 4-byte binary offsets, also stored MSB first. * * Following this, there are 'n' null-terminated strings. */ #define GET_WORD(P, V) do { \ (V) = 0; \ (V) = (P)[0]; (V) <<= 8; \ (V) += (P)[1]; (V) <<= 8; \ (V) += (P)[2]; (V) <<= 8; \ (V) += (P)[3]; \ } while (0) #define INTSZ 4 Elf_Arsym * _libelf_ar_process_symtab(Elf *e, size_t *count) { size_t n, nentries, off; Elf_Arsym *symtab, *sym; unsigned char *p, *s, *end; assert(e != NULL); assert(count != NULL); if (e->e_u.e_ar.e_rawsymtabsz < INTSZ) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } p = (unsigned char *) e->e_u.e_ar.e_rawsymtab; end = p + e->e_u.e_ar.e_rawsymtabsz; GET_WORD(p, nentries); p += INTSZ; if (nentries == 0 || p + nentries * INTSZ >= end) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } /* Allocate space for a nentries + a sentinel. */ if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } s = p + (nentries * INTSZ); /* start of the string table. */ for (n = nentries, sym = symtab; n > 0; n--) { off = 0; GET_WORD(p, off); sym->as_off = off; sym->as_hash = elf_hash(s); sym->as_name = s; p += INTSZ; sym++; for (; s < end && *s++ != '\0';) /* skip to next string */ ; if (s > end) { LIBELF_SET_ERROR(ARCHIVE, 0); free(symtab); return (NULL); } } /* Fill up the sentinel entry. */ sym->as_name = NULL; sym->as_hash = ~0UL; sym->as_off = (off_t) 0; *count = e->e_u.e_ar.e_symtabsz = nentries + 1; e->e_u.e_ar.e_symtab = symtab; return (symtab); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_getsyminfo.30000644000000000000000000000643211361411226017544 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETSYMINFO 3 .Os .Sh NAME .Nm gelf_getsyminfo , .Nm gelf_update_syminfo .Nd read and update symbol information .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Syminfo *" .Fn gelf_getsyminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" .Ft int .Fn gelf_update_syminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Syminfo and .Vt Elf64_Syminfo records in an ELF object. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_SUNW_syminfo . Argument .Ar ndx is the index of the record being retrieved or updated. The class-independent .Vt GElf_Syminfo structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getsyminfo retrieves class-dependent record at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar syminfo after translation to class-independent form. .Pp Function .Fn gelf_update_syminfo converts the class-independent record pointed to by argument .Ar syminfo to class-dependent form, and writes it to the record at index .Ar ndx in the data buffer described by argument .Ar data . .Sh RETURN VALUES Function .Fn gelf_getsyminfo returns the value of argument .Ar syminfo if successful, or NULL in case of an error. Function .Fn gelf_update_syminfo returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar syminfo were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of symbols in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section containing symbol information. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 , .Xr gelf_getsym 3 , .Xr gelf_update_sym 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_version.30000644000000000000000000000555611361411226016704 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 1, 2006 .Dt ELF_VERSION 3 .Os .Sh NAME .Nm elf_version .Nd retrieve or set ELF library operating version .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft unsigned int .Fn elf_version "unsigned int version" .Sh DESCRIPTION The .Fn elf_version function is used to query the current operating version of the ELF library, and to inform the ELF library about the application's desired operating version. .Pp If the argument .Ar version is .Dv EV_NONE , the .Fn elf_version function returns the currently configured operating version for the ELF library. .Pp If the argument .Ar version is not .Dv EV_NONE , and if argument .Ar version is supported by the ELF library, function .Fn elf_version sets the library's operating version to .Ar version , and returns the previous value of the operating version. If argument .Ar version cannot be supported, then the .Fn elf_version function returns .Dv EV_NONE . .Sh RETURN VALUES The .Fn elf_version function returns the currently configured ELF library version, or .Dv EV_NONE if an unsupported version is requested. .Sh EXAMPLES An application program would inform the ELF library about its desired operating version and check for an error using the following code snippet: .Bd -literal -offset indent if (elf_version(EV_CURRENT) == EV_NONE) err(EX_SOFTWARE, "ELF library too old"); .Ed .Sh ERRORS Function .Fn elf_version may fail with the following error: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er "ELF_E_VERSION" An unsupported library version number was requested. .El .Sh SEE ALSO .Xr elf 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_update.30000644000000000000000000002001311646565204016476 0ustar .\" Copyright (c) 2006,2007-2008 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd March 19, 2008 .Dt ELF_UPDATE 3 .Os .Sh NAME .Nm elf_update .Nd update an ELF descriptor .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft off_t .Fn elf_update "Elf *elf" "Elf_Cmd cmd" .Sh DESCRIPTION Function .Fn elf_update causes the library to recalculate the structure of an ELF object and optionally write out the image of the object to file. .Pp Argument .Ar elf is a descriptor to an ELF object. Argument .Ar cmd can take on the following values: .Bl -tag -width "ELF_C_WRITE" .It Dv ELF_C_NULL The library will recalculate structural information flagging modified structures with the .Dv ELF_F_DIRTY flag, but will not write back data to the underlying file image. .It Dv ELF_C_WRITE The library will recalculate structural information and will also write the new image to the underlying file. .El .Ss File Layout If the .Dv ELF_F_LAYOUT flag has been set on the ELF descriptor, the application assumes full responsibility for the layout of the ELF object. If this flag is not set, the ELF library will compute the layout of the file from its associated section descriptors. .Pp It is the application's responsibility to manage the following structure members in the ELF file: .Bl -tag -width indent .It "Executable Header" The ELF executable header is described in .Xr elf 5 . The following members of the ELF executable header are the application's responsibility: .Pp .Bl -tag -width "e_ident[EI_OSABI]" -compact .It Va e_entry Set to the desired entry address for executables. .It Va e_flags Set to the desired processor specific flags. .It Va "e_ident[EI_DATA]" Must be set to one of .Dv ELFDATA2LSB or .Dv ELFDATA2MSB . .It Va "e_ident[EI_OSABI]" Set to the OS ABI desired. For .Fx executables, this field should be set to .Dv ELFOSABI_FREEBSD . .It Va e_machine Set to the desired machine architecture, one of the .Dv EM_* values in .In sys/elf_common.h . .It Va e_phoff If the application is managing the object's layout, it must set this field to the file offset of the ELF program header table. .It Va e_shoff If the application is managing the object's layout, it must set this field to the file offset of the ELF section header table. .It Va e_shstrndx Set to the index of the string table containing section names. .It Va e_type Set to the type of the ELF object, one of the .Dv ET_* values in .In sys/elf_common.h . .It Va e_version Set to the desired version of the ELF object. .El .It "Program Header" All fields of the entries in the program header table are under application control. .It "Section Header" The ELF section header is described in .Xr elf 5 . The following members of the ELF section header are the application's responsibility: .Pp .Bl -tag -width "sh_addralign" -compact .It Va sh_addr Set to the physical memory address where the section should reside. .It Va sh_addralign If the application is managing the file layout, it must set this field to the desired alignment for the section's contents. This value must be a power of two. .It Va sh_entsize Set to the size of each entry, for sections containing fixed size elements, or set to zero for sections without fixed size elements. If the application is not managing file layout, it may leave this field as zero for those sections whose types known to the library. .It Va sh_flags Set to the desired section flags. .It Va sh_info Set as described in .Xr elf 5 . .It Va sh_link Set as described in .Xr elf 5 . .It Va sh_name Set to the index of the section's name in the string table containing section names. .It Va sh_offset If the application is managing the file layout, it must set this field to the file offset of the section's contents. .It Va sh_size If the application is managing the file layout, it must set this field to the file size of the section's contents. .It Va sh_type Set to the type of the section. .El .El .Pp Gaps in the coverage of the file's contents will be set to the fill value specified by .Xr elf_fill 3 . .Pp If the application has requested full control over the file's layout by setting the .Dv ELF_F_LAYOUT flag on the ELF descriptor, it should ensure that there are no gaps in the coverage of the file's contents. .Pp All pointers to .Vt Elf_Scn and .Vt Elf_Data descriptors associated with descriptor .Ar elf should be considered as invalid after a call to .Fn elf_update . .Sh RETURN VALUES Function .Fn elf_update returns the total size of the file image if successful, or -1 if an error occurred. .Sh ERRORS This function may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was null. .It Bq Er ELF_E_ARGUMENT Argument .Ar cmd was not recognized. .It Bq Er ELF_E_ARGUMENT The argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_CLASS The .Va e_ident[EI_CLASS] field of the executable header of argument .Ar elf did not match the class of the file. .It Bq Er ELF_E_DATA An .Vt Elf_Data descriptor contained in argument .Ar elf specified a type incompatible with its containing section. .It Bq Er ELF_E_HEADER The ELF header in argument .Ar elf requested a different byte order from the byte order already associated with the file. .It Bq Er ELF_E_IO An I/O error was encountered. .It Bq Er ELF_E_LAYOUT An .Vt Elf_Data descriptor contained in argument .Ar elf specified an alignment incompatible with its containing section. .It Bq Er ELF_E_LAYOUT Argument .Ar elf contained section descriptors that overlapped in extent. .It Bq Er ELF_E_LAYOUT Argument .Ar elf contained section descriptors that were incorrectly aligned or were too small for their data. .It Bq Er ELF_E_LAYOUT The flag .Dv ELF_F_LAYOUT was set on the Elf descriptor and the section header table overlapped an extent in the object mapped by a section descriptor. .It Bq Er ELF_E_MODE An .Dv ELF_C_WRITE operation was requested with an ELF descriptor that was not opened for writing or updating. .It Bq Er ELF_E_SECTION Argument .Ar elf contained a section with an unrecognized type. .It Bq Er ELF_E_SECTION The section header at index .Dv SHN_UNDEF had an illegal section type. .It Bq Er ELF_E_SEQUENCE An .Dv ELF_C_WRITE operation was requested after a prior call to .Fn elf_cntl elf ELF_C_FDDONE disassociated the ELF descriptor .Ar elf from its underlying file. .It Bq Er ELF_E_VERSION Argument .Ar elf had an unsupported version or contained an .Vt Elf_Data descriptor with an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf32_getphdr 3 , .Xr elf32_newehdr 3 , .Xr elf32_newphdr 3 , .Xr elf64_getehdr 3 , .Xr elf64_getphdr 3 , .Xr elf64_newehdr 3 , .Xr elf64_newphdr 3 , .Xr elf_cntl 3 , .Xr elf_fill 3 , .Xr elf_flagehdr 3 , .Xr elf_flagelf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr elf_newdata 3 , .Xr elf_newscn 3 , .Xr elf_rawdata 3 , .Xr gelf 3 , .Xr gelf_newehdr 3 , .Xr gelf_newphdr 3 , .Xr elf 5 freebsd-libs-10.1~svn273304/lib/libelf/elf_getarsym.c0000644000000000000000000000352210525402563017126 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" Elf_Arsym * elf_getarsym(Elf *ar, size_t *ptr) { size_t n; Elf_Arsym *symtab; n = 0; symtab = NULL; if (ar == NULL || ar->e_kind != ELF_K_AR) LIBELF_SET_ERROR(ARGUMENT, 0); else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL) n = ar->e_u.e_ar.e_symtabsz; else if (ar->e_u.e_ar.e_rawsymtab) symtab = _libelf_ar_process_symtab(ar, &n); else LIBELF_SET_ERROR(ARCHIVE, 0); if (ptr) *ptr = n; return (symtab); } freebsd-libs-10.1~svn273304/lib/libelf/elf_strptr.30000644000000000000000000000640611753270526016563 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd December 16, 2006 .Dt ELF_STRPTR 3 .Os .Sh NAME .Nm elf_strptr .Nd retrieve a string pointer in a string table .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "char *" .Fn elf_strptr "Elf *elf" "size_t scndx" "size_t stroffset" .Sh DESCRIPTION Function .Fn elf_strptr allows an application to convert a string table offset to a string pointer, correctly translating the offset in the presence of multiple .Vt Elf_Data descriptors covering the contents of the section. .Pp Argument .Ar elf is a descriptor for an ELF object. Argument .Ar scndx is the section index for an ELF string table. Argument .Ar stroffset is the index of the desired string in the string table. .Sh RETURN VALUES Function .Fn elf_strptr returns a valid pointer on success or NULL in case an error was encountered. .Sh ERRORS .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_ARGUMENT Argument .Ar scndx was not the section index for a string table. .It Bq Er ELF_E_ARGUMENT Argument .Ar stroffset exceeded the size of the string table. .It Bq Er ELF_E_ARGUMENT Argument .Ar stroffset index an unallocated region of the string table. .It Bq Er ELF_E_DATA Offset .Ar stroffset indexed a region that was not covered by any Elf_Data descriptor. .It Bq Er ELF_E_DATA An erroneous .Vt Elf_Data descriptor was part of the section specified by argument .Ar scndx . .It Bq Er ELF_E_HEADER ELF descriptor .Ar elf contained an invalid section header. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected. .It Bq Er ELF_E_SECTION Section .Ar scndx contained a malformed section header. .It Bq Er ELF_E_SECTION The ELF descriptor in argument .Ar elf did not adhere to the conventions used for extended numbering. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getshdr 3 , .Xr elf64_getshdr 3 , .Xr elf_getdata 3 , .Xr elf_rawdata 3 , .Xr gelf 3 , .Xr gelf_getshdr 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_cntl.c0000644000000000000000000000345010525402563016233 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" int elf_cntl(Elf *e, Elf_Cmd c) { if (e == NULL || (c != ELF_C_FDDONE && c != ELF_C_FDREAD)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (-1); } if (e->e_parent) { LIBELF_SET_ERROR(ARCHIVE, 0); return (-1); } if (c == ELF_C_FDREAD) { if (e->e_cmd == ELF_C_WRITE) { LIBELF_SET_ERROR(MODE, 0); return (-1); } else return (0); } e->e_fd = -1; return 0; } freebsd-libs-10.1~svn273304/lib/libelf/elf_shstrndx.c0000644000000000000000000000445411421562272017155 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" static int _libelf_getshdrstrndx(Elf *e, size_t *strndx) { void *eh; int ec; if (e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (-1); } if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) return (-1); *strndx = e->e_u.e_elf.e_strndx; return (0); } int elf_getshdrstrndx(Elf *e, size_t *strndx) { return (_libelf_getshdrstrndx(e, strndx)); } int elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */ { return (_libelf_getshdrstrndx(e, strndx) >= 0); } int elf_setshstrndx(Elf *e, size_t strndx) { void *eh; int ec; if (e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } return (_libelf_setshstrndx(e, eh, ec, strndx)); } freebsd-libs-10.1~svn273304/lib/libelf/libelf.c0000644000000000000000000000360410525402563015703 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" struct _libelf_globals _libelf = { .libelf_arch = ELF_ARCH, .libelf_byteorder = ELF_TARG_DATA, .libelf_class = ELF_TARG_CLASS, .libelf_error = 0, .libelf_fillchar = 0, .libelf_version = EV_NONE }; #if defined(LIBELF_TEST_HOOKS) int _libelf_get_elf_class(Elf *elf) { return elf->e_class; } void _libelf_set_elf_class(Elf *elf, int c) { elf->e_class = c; } #endif /* LIBELF_TEST_HOOKS */ freebsd-libs-10.1~svn273304/lib/libelf/elf_errmsg.30000644000000000000000000000672411361411226016514 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 11, 2006 .Dt ELF_ERRMSG 3 .Os .Sh NAME .Nm elf_errmsg , .Nm elf_errno .Nd ELF library error message handling .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_errno "void" .Ft "const char *" .Fn elf_errmsg "int error" .Sh DESCRIPTION When an error occurs during an ELF library API call, the library encodes the error using an error number and stores the error number internally for retrieval by the application at a later point of time. Error numbers may contain an OS supplied error code in addition to an ELF API specific error code. An error number value of zero indicates no error. .Pp Function .Fn elf_errno is used to retrieve the last error recorded by the ELF library. Invoking this function has the side-effect of resetting the ELF library's recorded error number to zero. .Pp The function .Fn elf_errmsg returns a null-terminated string with a human readable description of the error specified in argument .Ar error . A zero value for argument .Ar error retrieves the most recent error encountered by the ELF library. An argument value of -1 behaves identically, except that it guarantees a non-NULL return from .Fn elf_errmsg . .Sh RETURN VALUES Function .Fn elf_errno returns a non-zero value encoding the last error encountered by the ELF library, or zero if no error was encountered. .Pp Function .Fn elf_errmsg returns a pointer to library local storage for non-zero values of argument .Ar error . With a zero argument, the function will return a NULL pointer if no error had been encountered by the library, or will return a pointer to library local storage containing an appropriate message otherwise. .Sh EXAMPLES Clearing the ELF library's recorded error number can be accomplished by invoking .Fn elf_errno and discarding its return value. .Bd -literal -offset indent /* clear error */ (void) elf_errno(); .Ed .Pp Retrieving a human-readable description of the current error number can be done with the following snippet: .Bd -literal -offset indent int err; const char *errmsg; \&... err = elf_errno(); if (err != 0) errmsg = elf_errmsg(err); .Ed .Sh SEE ALSO .Xr elf 3 , .Xr gelf 3 .Sh BUGS Function .Fn elf_errmsg is not localized. freebsd-libs-10.1~svn273304/lib/libelf/elf_errmsg.c0000644000000000000000000000637012040164212016564 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" /* * Retrieve a human readable translation for an error message. */ static const char *_libelf_errors[] = { #define DEFINE_ERROR(N,S) [ELF_E_##N] = S DEFINE_ERROR(NONE, "No Error"), DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), DEFINE_ERROR(ARGUMENT, "Invalid argument"), DEFINE_ERROR(CLASS, "ELF class mismatch"), DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), DEFINE_ERROR(IO, "I/O error"), DEFINE_ERROR(LAYOUT, "Layout constraint violation"), DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), DEFINE_ERROR(RANGE, "Value out of range of target"), DEFINE_ERROR(RESOURCE, "Resource exhaustion"), DEFINE_ERROR(SECTION, "Invalid section descriptor"), DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), DEFINE_ERROR(UNIMPL, "Unimplemented feature"), DEFINE_ERROR(VERSION, "Unknown ELF API version"), DEFINE_ERROR(NUM, "Unknown error") #undef DEFINE_ERROR }; const char * elf_errmsg(int error) { int oserr; if (error == 0 && (error = LIBELF_PRIVATE(error)) == 0) return NULL; else if (error == -1) error = LIBELF_PRIVATE(error); oserr = error >> LIBELF_OS_ERROR_SHIFT; error &= LIBELF_ELF_ERROR_MASK; if (error < 0 || error >= ELF_E_NUM) return _libelf_errors[ELF_E_NUM]; if (oserr) { strlcpy(LIBELF_PRIVATE(msg), _libelf_errors[error], sizeof(LIBELF_PRIVATE(msg))); strlcat(LIBELF_PRIVATE(msg), ": ", sizeof(LIBELF_PRIVATE(msg))); strlcat(LIBELF_PRIVATE(msg), strerror(oserr), sizeof(LIBELF_PRIVATE(msg))); return (const char *)&LIBELF_PRIVATE(msg); } return _libelf_errors[error]; } #if defined(LIBELF_TEST_HOOKS) const char * _libelf_get_unknown_error_message(void) { return _libelf_errors[ELF_E_NUM]; } const char * _libelf_get_no_error_message(void) { return _libelf_errors[0]; } #endif /* LIBELF_TEST_HOOKS */ freebsd-libs-10.1~svn273304/lib/libelf/libelf_convert.m40000644000000000000000000005377711533156347017567 0ustar /*- * Copyright (c) 2006-2008 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include "_libelf.h" /* WARNING: GENERATED FROM __file__. */ /* * Macros to swap various integral quantities. */ #define SWAP_HALF(X) do { \ uint16_t _x = (uint16_t) (X); \ uint16_t _t = _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ (X) = _t; \ } while (0) #define SWAP_WORD(X) do { \ uint32_t _x = (uint32_t) (X); \ uint32_t _t = _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ (X) = _t; \ } while (0) #define SWAP_ADDR32(X) SWAP_WORD(X) #define SWAP_OFF32(X) SWAP_WORD(X) #define SWAP_SWORD(X) SWAP_WORD(X) #define SWAP_WORD64(X) do { \ uint64_t _x = (uint64_t) (X); \ uint64_t _t = _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ (X) = _t; \ } while (0) #define SWAP_ADDR64(X) SWAP_WORD64(X) #define SWAP_LWORD(X) SWAP_WORD64(X) #define SWAP_OFF64(X) SWAP_WORD64(X) #define SWAP_SXWORD(X) SWAP_WORD64(X) #define SWAP_XWORD(X) SWAP_WORD64(X) /* * Write out various integral values. The destination pointer could * be unaligned. Values are written out in native byte order. The * destination pointer is incremented after the write. */ #define WRITE_BYTE(P,X) do { \ char *const _p = (char *) (P); \ _p[0] = (char) (X); \ (P) = _p + 1; \ } while (0) #define WRITE_HALF(P,X) do { \ uint16_t _t = (X); \ char *const _p = (char *) (P); \ const char *const _q = (char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ (P) = _p + 2; \ } while (0) #define WRITE_WORD(P,X) do { \ uint32_t _t = (X); \ char *const _p = (char *) (P); \ const char *const _q = (char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ _p[2] = _q[2]; \ _p[3] = _q[3]; \ (P) = _p + 4; \ } while (0) #define WRITE_ADDR32(P,X) WRITE_WORD(P,X) #define WRITE_OFF32(P,X) WRITE_WORD(P,X) #define WRITE_SWORD(P,X) WRITE_WORD(P,X) #define WRITE_WORD64(P,X) do { \ uint64_t _t = (X); \ char *const _p = (char *) (P); \ const char *const _q = (char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ _p[2] = _q[2]; \ _p[3] = _q[3]; \ _p[4] = _q[4]; \ _p[5] = _q[5]; \ _p[6] = _q[6]; \ _p[7] = _q[7]; \ (P) = _p + 8; \ } while (0) #define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) #define WRITE_LWORD(P,X) WRITE_WORD64(P,X) #define WRITE_OFF64(P,X) WRITE_WORD64(P,X) #define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) #define WRITE_XWORD(P,X) WRITE_WORD64(P,X) #define WRITE_IDENT(P,X) do { \ (void) memcpy((P), (X), sizeof((X))); \ (P) = (P) + EI_NIDENT; \ } while (0) /* * Read in various integral values. The source pointer could be * unaligned. Values are read in native byte order. The source * pointer is incremented appropriately. */ #define READ_BYTE(P,X) do { \ const char *const _p = \ (const char *) (P); \ (X) = _p[0]; \ (P) = (P) + 1; \ } while (0) #define READ_HALF(P,X) do { \ uint16_t _t; \ char *const _q = (char *) &_t; \ const char *const _p = \ (const char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ (P) = (P) + 2; \ (X) = _t; \ } while (0) #define READ_WORD(P,X) do { \ uint32_t _t; \ char *const _q = (char *) &_t; \ const char *const _p = \ (const char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ _q[2] = _p[2]; \ _q[3] = _p[3]; \ (P) = (P) + 4; \ (X) = _t; \ } while (0) #define READ_ADDR32(P,X) READ_WORD(P,X) #define READ_OFF32(P,X) READ_WORD(P,X) #define READ_SWORD(P,X) READ_WORD(P,X) #define READ_WORD64(P,X) do { \ uint64_t _t; \ char *const _q = (char *) &_t; \ const char *const _p = \ (const char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ _q[2] = _p[2]; \ _q[3] = _p[3]; \ _q[4] = _p[4]; \ _q[5] = _p[5]; \ _q[6] = _p[6]; \ _q[7] = _p[7]; \ (P) = (P) + 8; \ (X) = _t; \ } while (0) #define READ_ADDR64(P,X) READ_WORD64(P,X) #define READ_LWORD(P,X) READ_WORD64(P,X) #define READ_OFF64(P,X) READ_WORD64(P,X) #define READ_SXWORD(P,X) READ_WORD64(P,X) #define READ_XWORD(P,X) READ_WORD64(P,X) #define READ_IDENT(P,X) do { \ (void) memcpy((X), (P), sizeof((X))); \ (P) = (P) + EI_NIDENT; \ } while (0) #define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) divert(-1) /* * Generate conversion routines for converting between in-memory and * file representations of Elf data structures. * * `In-memory' representations of an Elf data structure use natural * alignments and native byte ordering. This allows arithmetic and * casting to work as expected. On the other hand the `file' * representation of an ELF data structure could be packed tighter * than its `in-memory' representation, and could be of a differing * byte order. An additional complication is that `ar' only pads data * to even addresses and so ELF archive member data being read from * inside an `ar' archive could end up at misaligned memory addresses. * * Consequently, casting the `char *' pointers that point to memory * representations (i.e., source pointers for the *_tof() functions * and the destination pointers for the *_tom() functions), is safe, * as these pointers should be correctly aligned for the memory type * already. However, pointers to file representations have to be * treated as being potentially unaligned and no casting can be done. */ include(SRCDIR`/elf_types.m4') /* * `IGNORE'_* flags turn off generation of template code. */ define(`IGNORE', `define(IGNORE_$1`'32, 1) define(IGNORE_$1`'64, 1)') IGNORE(MOVEP) IGNORE(NOTE) IGNORE(GNUHASH) define(IGNORE_BYTE, 1) /* 'lator, leave 'em bytes alone */ define(IGNORE_GNUHASH, 1) define(IGNORE_NOTE, 1) define(IGNORE_SXWORD32, 1) define(IGNORE_XWORD32, 1) /* * `BASE'_XXX flags cause class agnostic template functions * to be generated. */ define(`BASE_BYTE', 1) define(`BASE_HALF', 1) define(`BASE_NOTE', 1) define(`BASE_WORD', 1) define(`BASE_LWORD', 1) define(`BASE_SWORD', 1) define(`BASE_XWORD', 1) define(`BASE_SXWORD', 1) /* * `SIZEDEP'_XXX flags cause 32/64 bit variants to be generated * for each primitive type. */ define(`SIZEDEP_ADDR', 1) define(`SIZEDEP_OFF', 1) /* * `Primitive' ELF types are those that are an alias for an integral * type. They have no internal structure. These can be copied using * a `memcpy()', and byteswapped in straightforward way. * * Macro use: * `$1': Name of the ELF type. * `$2': C structure name suffix * `$3': ELF class specifier for symbols, one of [`', `32', `64'] * `$4': ELF class specifier for types, one of [`32', `64'] */ define(`MAKEPRIM_TO_F',` static int libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, int byteswap) { Elf$4_$2 t, *s = (Elf$4_$2 *) (uintptr_t) src; size_t c; (void) dsz; if (!byteswap) { (void) memcpy(dst, src, count * sizeof(*s)); return (1); } for (c = 0; c < count; c++) { t = *s++; SWAP_$1$3(t); WRITE_$1$3(dst,t); } return (1); } ') define(`MAKEPRIM_TO_M',` static int libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count, int byteswap) { Elf$4_$2 t, *d = (Elf$4_$2 *) (uintptr_t) dst; size_t c; if (dsz < count * sizeof(Elf$4_$2)) return (0); if (!byteswap) { (void) memcpy(dst, src, count * sizeof(*d)); return (1); } for (c = 0; c < count; c++) { READ_$1$3(src,t); SWAP_$1$3(t); *d++ = t; } return (1); } ') define(`SWAP_FIELD', `ifdef(`IGNORE_'$2,`', `ifelse(BASE_$2,1, `SWAP_$2(t.$1); ', `ifelse($2,BYTE,`', `ifelse($2,IDENT,`', `SWAP_$2'SZ()`(t.$1); ')')')')') define(`SWAP_MEMBERS', `ifelse($#,1,`/**/', `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') define(`SWAP_STRUCT', `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') define(`WRITE_FIELD', `ifelse(BASE_$2,1, `WRITE_$2(dst,t.$1); ', `ifelse($2,IDENT, `WRITE_$2(dst,t.$1); ', `WRITE_$2'SZ()`(dst,t.$1); ')')') define(`WRITE_MEMBERS', `ifelse($#,1,`/**/', `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') define(`WRITE_STRUCT', `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') define(`READ_FIELD', `ifelse(BASE_$2,1, `READ_$2(s,t.$1); ', `ifelse($2,IDENT, `READ_$2(s,t.$1); ', `READ_$2'SZ()`(s,t.$1); ')')') define(`READ_MEMBERS', `ifelse($#,1,`/**/', `READ_FIELD($1)READ_MEMBERS(shift($@))')') define(`READ_STRUCT', `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') /* * Converters for non-integral ELF data structures. * * When converting data to file representation, the source pointer * will be naturally aligned for a data structure's in-memory * representation. When converting data to memory, the destination * pointer will be similarly aligned. * * For in-place conversions, when converting to file representations, * the source buffer is large enough to hold `file' data. When * converting from file to memory, we need to be careful to work * `backwards', to avoid overwriting unconverted data. * * Macro use: * `$1': Name of the ELF type. * `$2': C structure name suffix. * `$3': ELF class specifier, one of [`', `32', `64'] */ define(`MAKE_TO_F', `ifdef(`IGNORE_'$1$3,`',` static int libelf_cvt$3_$1_tof(char *dst, size_t dsz, char *src, size_t count, int byteswap) { Elf$3_$2 t, *s; size_t c; (void) dsz; s = (Elf$3_$2 *) (uintptr_t) src; for (c = 0; c < count; c++) { t = *s++; if (byteswap) { SWAP_STRUCT($2,$3) } WRITE_STRUCT($2,$3) } return (1); } ')') define(`MAKE_TO_M', `ifdef(`IGNORE_'$1$3,`',` static int libelf_cvt$3_$1_tom(char *dst, size_t dsz, char *src, size_t count, int byteswap) { Elf$3_$2 t, *d; char *s,*s0; size_t fsz; fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); s0 = (char *) src + (count - 1) * fsz; if (dsz < count * sizeof(Elf$3_$2)) return (0); while (count--) { s = s0; READ_STRUCT($2,$3) if (byteswap) { SWAP_STRUCT($2,$3) } *d-- = t; s0 -= fsz; } return (1); } ')') /* * Make type convertor functions from the type definition * of the ELF type: * - if the type is a base (i.e., `primitive') type: * - if it is marked as to be ignored (i.e., `IGNORE_'TYPE) * is defined, we skip the code generation step. * - if the type is declared as `SIZEDEP', then 32 and 64 bit * variants of the conversion functions are generated. * - otherwise a 32 bit variant is generated. * - if the type is a structure type, we generate 32 and 64 bit * variants of the conversion functions. */ define(`MAKE_TYPE_CONVERTER', `#if __FreeBSD_version >= $3 /* $1 */ ifdef(`BASE'_$1, `ifdef(`IGNORE_'$1,`', `MAKEPRIM_TO_F($1,$2,`',64) MAKEPRIM_TO_M($1,$2,`',64)')', `ifdef(`SIZEDEP_'$1, `MAKEPRIM_TO_F($1,$2,32,32)dnl MAKEPRIM_TO_M($1,$2,32,32)dnl MAKEPRIM_TO_F($1,$2,64,64)dnl MAKEPRIM_TO_M($1,$2,64,64)', `MAKE_TO_F($1,$2,32)dnl MAKE_TO_F($1,$2,64)dnl MAKE_TO_M($1,$2,32)dnl MAKE_TO_M($1,$2,64)')') #endif /* $1 */ ') define(`MAKE_TYPE_CONVERTERS', `ifelse($#,1,`', `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') divert(0) /* * Sections of type ELF_T_BYTE are never byteswapped, consequently a * simple memcpy suffices for both directions of conversion. */ static int libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, int byteswap) { (void) byteswap; if (dsz < count) return (0); if (dst != src) (void) memcpy(dst, src, count); return (1); } MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) #if __FreeBSD_version >= 800062 /* * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit * words. Bloom filter data comes next, followed by hash buckets and the * hash chain. * * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit * wide on ELFCLASS32 objects. The other objects in this section are 32 * bits wide. * * Argument `srcsz' denotes the number of bytes to be converted. In the * 32-bit case we need to translate `srcsz' to a count of 32-bit words. */ static int libelf_cvt32_GNUHASH_tom(char *dst, size_t dsz, char *src, size_t srcsz, int byteswap) { return (libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), byteswap)); } static int libelf_cvt32_GNUHASH_tof(char *dst, size_t dsz, char *src, size_t srcsz, int byteswap) { return (libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), byteswap)); } static int libelf_cvt64_GNUHASH_tom(char *dst, size_t dsz, char *src, size_t srcsz, int byteswap) { size_t sz; uint64_t t64, *bloom64; Elf_GNU_Hash_Header *gh; uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; uint32_t *buckets, *chains; sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) return (0); /* Read in the section header and byteswap if needed. */ READ_WORD(src, nbuckets); READ_WORD(src, symndx); READ_WORD(src, maskwords); READ_WORD(src, shift2); srcsz -= sz; if (byteswap) { SWAP_WORD(nbuckets); SWAP_WORD(symndx); SWAP_WORD(maskwords); SWAP_WORD(shift2); } /* Check source buffer and destination buffer sizes. */ sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) return (0); gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; gh->gh_nbuckets = nbuckets; gh->gh_symndx = symndx; gh->gh_maskwords = maskwords; gh->gh_shift2 = shift2; dsz -= sizeof(Elf_GNU_Hash_Header); dst += sizeof(Elf_GNU_Hash_Header); bloom64 = (uint64_t *) (uintptr_t) dst; /* Copy bloom filter data. */ for (n = 0; n < maskwords; n++) { READ_XWORD(src, t64); if (byteswap) SWAP_XWORD(t64); bloom64[n] = t64; } /* The hash buckets follows the bloom filter. */ dst += maskwords * sizeof(uint64_t); buckets = (uint32_t *) (uintptr_t) dst; for (n = 0; n < nbuckets; n++) { READ_WORD(src, t32); if (byteswap) SWAP_WORD(t32); buckets[n] = t32; } dst += nbuckets * sizeof(uint32_t); /* The hash chain follows the hash buckets. */ dsz -= sz; srcsz -= sz; if (dsz < srcsz) /* Destination lacks space. */ return (0); nchains = srcsz / sizeof(uint32_t); chains = (uint32_t *) (uintptr_t) dst; for (n = 0; n < nchains; n++) { READ_WORD(src, t32); if (byteswap) SWAP_WORD(t32); *chains++ = t32; } return (1); } static int libelf_cvt64_GNUHASH_tof(char *dst, size_t dsz, char *src, size_t srcsz, int byteswap) { uint32_t *s32; size_t sz, hdrsz; uint64_t *s64, t64; Elf_GNU_Hash_Header *gh; uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) return (0); gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; t0 = nbuckets = gh->gh_nbuckets; t1 = gh->gh_symndx; t2 = maskwords = gh->gh_maskwords; t3 = gh->gh_shift2; src += sizeof(Elf_GNU_Hash_Header); srcsz -= sizeof(Elf_GNU_Hash_Header); dsz -= hdrsz; sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * sizeof(uint64_t); if (srcsz < sz || dsz < sz) return (0); /* Write out the header. */ if (byteswap) { SWAP_WORD(t0); SWAP_WORD(t1); SWAP_WORD(t2); SWAP_WORD(t3); } WRITE_WORD(dst, t0); WRITE_WORD(dst, t1); WRITE_WORD(dst, t2); WRITE_WORD(dst, t3); /* Copy the bloom filter and the hash table. */ s64 = (uint64_t *) (uintptr_t) src; for (n = 0; n < maskwords; n++) { t64 = *s64++; if (byteswap) SWAP_XWORD(t64); WRITE_WORD64(dst, t64); } s32 = (uint32_t *) s64; for (n = 0; n < nbuckets; n++) { t32 = *s32++; if (byteswap) SWAP_WORD(t32); WRITE_WORD(dst, t32); } srcsz -= sz; dsz -= sz; /* Copy out the hash chains. */ if (dsz < srcsz) return (0); nchains = srcsz / sizeof(uint32_t); for (n = 0; n < nchains; n++) { t32 = *s32++; if (byteswap) SWAP_WORD(t32); WRITE_WORD(dst, t32); } return (1); } #endif /* * Elf_Note structures comprise a fixed size header followed by variable * length strings. The fixed size header needs to be byte swapped, but * not the strings. * * Argument `count' denotes the total number of bytes to be converted. * The destination buffer needs to be at least `count' bytes in size. */ static int libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, int byteswap) { uint32_t namesz, descsz, type; Elf_Note *en; size_t sz, hdrsz; if (dsz < count) /* Destination buffer is too small. */ return (0); hdrsz = 3 * sizeof(uint32_t); if (count < hdrsz) /* Source too small. */ return (0); if (!byteswap) { (void) memcpy(dst, src, count); return (1); } /* Process all notes in the section. */ while (count > hdrsz) { /* Read the note header. */ READ_WORD(src, namesz); READ_WORD(src, descsz); READ_WORD(src, type); /* Translate. */ SWAP_WORD(namesz); SWAP_WORD(descsz); SWAP_WORD(type); /* Copy out the translated note header. */ en = (Elf_Note *) (uintptr_t) dst; en->n_namesz = namesz; en->n_descsz = descsz; en->n_type = type; dsz -= sizeof(Elf_Note); dst += sizeof(Elf_Note); count -= hdrsz; ROUNDUP2(namesz, 4); ROUNDUP2(descsz, 4); sz = namesz + descsz; if (count < sz || dsz < sz) /* Buffers are too small. */ return (0); (void) memcpy(dst, src, sz); src += sz; dst += sz; count -= sz; dsz -= sz; } return (1); } static int libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, int byteswap) { uint32_t namesz, descsz, type; Elf_Note *en; size_t sz; if (dsz < count) return (0); if (!byteswap) { (void) memcpy(dst, src, count); return (1); } while (count > sizeof(Elf_Note)) { en = (Elf_Note *) (uintptr_t) src; namesz = en->n_namesz; descsz = en->n_descsz; type = en->n_type; SWAP_WORD(namesz); SWAP_WORD(descsz); SWAP_WORD(type); WRITE_WORD(dst, namesz); WRITE_WORD(dst, descsz); WRITE_WORD(dst, type); src += sizeof(Elf_Note); ROUNDUP2(namesz, 4); ROUNDUP2(descsz, 4); sz = namesz + descsz; if (count < sz) sz = count; (void) memcpy(dst, src, sz); src += sz; dst += sz; count -= sz; } return (1); } struct converters { int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt, int byteswap); int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt, int byteswap); int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt, int byteswap); int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt, int byteswap); }; divert(-1) define(`CONV', `ifdef(`IGNORE_'$1$2, `.$3$2 = NULL', `ifdef(`BASE_'$1, `.$3$2 = libelf_cvt_$1_$3', `ifdef(`SIZEDEP_'$1, `.$3$2 = libelf_cvt_$1$2_$3', `.$3$2 = libelf_cvt$2_$1_$3')')')') define(`CONVERTER_NAME', `ifdef(`IGNORE_'$1,`', `#if __FreeBSD_version >= $3 [ELF_T_$1] = { CONV($1,32,tof), CONV($1,32,tom), CONV($1,64,tof), CONV($1,64,tom) }, #endif ')') define(`CONVERTER_NAMES', `ifelse($#,1,`', `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') undefine(`IGNORE_BYTE32', `IGNORE_BYTE64') divert(0) static struct converters cvt[ELF_T_NUM] = { CONVERTER_NAMES(ELF_TYPE_LIST) /* * Types that needs hand-coded converters follow. */ [ELF_T_BYTE] = { .tof32 = libelf_cvt_BYTE_tox, .tom32 = libelf_cvt_BYTE_tox, .tof64 = libelf_cvt_BYTE_tox, .tom64 = libelf_cvt_BYTE_tox }, #if __FreeBSD_version >= 800062 [ELF_T_GNUHASH] = { .tof32 = libelf_cvt32_GNUHASH_tof, .tom32 = libelf_cvt32_GNUHASH_tom, .tof64 = libelf_cvt64_GNUHASH_tof, .tom64 = libelf_cvt64_GNUHASH_tom }, #endif [ELF_T_NOTE] = { .tof32 = libelf_cvt_NOTE_tof, .tom32 = libelf_cvt_NOTE_tom, .tof64 = libelf_cvt_NOTE_tof, .tom64 = libelf_cvt_NOTE_tom } }; int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) { assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); if (t >= ELF_T_NUM || (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) return (NULL); return ((elfclass == ELFCLASS32) ? (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); } freebsd-libs-10.1~svn273304/lib/libelf/gelf.30000644000000000000000000001430711762351436015313 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd September 1, 2006 .Dt GELF 3 .Os .Sh NAME .Nm GElf .Nd class-independent API for ELF manipulation .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Sh DESCRIPTION This manual page describes a class independent API for manipulating ELF objects. This API allows an application to operate on ELF descriptors without needing to the know the ELF class of the descriptor. .Pp The GElf API may be used alongside the ELF API without restriction. .Ss GElf Data Structures The GElf API defines the following class-independent data structures: .Bl -tag -width GElf_Sxword .It Vt GElf_Addr A representation of ELF addresses. .It Vt GElf_Dyn A class-independent representation of ELF .Sy .dynamic section entries. .It Vt GElf_Ehdr A class-independent representation of an ELF Executable Header. .It Vt GElf_Half An unsigned 16 bit quantity. .It Vt GElf_Off A class-independent representation of a ELF offset. .It Vt GElf_Phdr A class-independent representation of an ELF Program Header Table entry. .It Vt GElf_Rel A class-independent representation of an ELF relocation entry. .It Vt GElf_Rela A class-independent representation of an ELF relocation entry with addend. .It Vt GElf_Shdr A class-independent representation of an ELF Section Header Table entry. .It Vt GElf_Sword A signed 32 bit quantity. .It Vt GElf_Sxword A signed 64 bit quantity. .It Vt GElf_Sym A class-independent representation of an ELF symbol table entry. .It Vt GElf_Word An unsigned 32 bit quantity. .It Vt GElf_Xword An unsigned 64 bit quantity. .El .Pp These data structures are sized to be compatible with the corresponding 64 bit ELF structures, and have the same internal structure as their 64 bit class-dependent counterparts. Class-dependent ELF structures are described in .Xr elf 5 . .Ss GElf Programming Model GElf functions always return a .Em copy of the underlying (class-dependent) ELF data structure. The programming model with GElf is as follows: .Bl -enum .It An application will retrieve data from an ELF descriptor using a .Fn gelf_get_* function. This will copy out data into a private .Vt GElf_* data structure. .It The application will work with its private copy of the GElf structure. .It Once done, the application copies the new values back to the underlying ELF data structure using the .Fn gelf_update_* functions. .It The application will then use the .Fn elf_flag* APIs to indicate to the ELF library that an ELF data structure is dirty. .El .Pp When updating an underlying 32 bit ELF data structure, the GElf routines will signal an error if a GElf value is out of range for the underlying ELF data type. .Ss Namespace use The GElf interface uses the following symbols: .Bl -tag -width 8n .It GElf_* Class-independent data types. .It gelf_* For functions defined in the API set. .El .Ss GElf Programming APIs This section provides an overview of the GElf programming APIs. Further information is provided in the manual page of each function listed here. .Bl -tag -width 2n .It "Allocating ELF Data Structures" .Bl -tag -width 19n -compact .It Fn gelf_newehdr Allocate a new ELF Executable Header. .It Fn gelf_newphdr Allocate a new ELF Program Header Table. .El .It "Data Translation" .Bl -tag -width 19n -compact .It Fn gelf_xlatetof Translate the native representation of an ELF data structure to its file representation. .It Fn gelf_xlatetom Translate from the file representation of an ELF data structure to a native representation. .El .It "Retrieving ELF Data" .Bl -tag -width 19n -compact .It Fn gelf_getdyn Retrieve an ELF .Sy .dynamic table entry. .It Fn gelf_getehdr Retrieve an ELF Executable Header from the underlying ELF descriptor. .It Fn gelf_getphdr Retrieve an ELF Program Header Table entry from the underlying ELF descriptor. .It Fn gelf_getrel Retrieve an ELF relocation entry. .It Fn gelf_getrela Retrieve an ELF relocation entry with addend. .It Fn gelf_getshdr Retrieve an ELF Section Header Table entry from the underlying ELF descriptor. .It Fn gelf_getsym Retrieve an ELF symbol table entry. .El .It Queries .Bl -tag -width 19n -compact .It Fn gelf_checksum Retrieves the ELF checksum for an ELF descriptor. .It Fn gelf_fsize Retrieves the size of the file representation of an ELF type. .It Fn gelf_getclass Retrieves the ELF class of an ELF descriptor. .El .It "Updating ELF Data" .Bl -tag -width 19n -compact .It Fn gelf_update_dyn Copy back an ELF .Sy .dynamic Table entry. .It Fn gelf_update_phdr Copy back an ELF Program Header Table entry. .It Fn gelf_update_rel Copy back an ELF relocation entry. .It Fn gelf_update_rela Copy back an ELF relocation with addend entry. .It Fn gelf_update_shdr Copy back an ELF Section Header Table entry. .It Fn gelf_update_sym Copy back an ELF symbol table entry. .El .El .Sh SEE ALSO .Xr elf 3 , .Xr elf 5 .Sh HISTORY The GELF(3) API first appeared in System V Release 4. This implementation of the API first appeared in .Fx 7.0 . .Sh AUTHORS The GElf API was implemented by .An "Joseph Koshy" .Aq jkoshy@FreeBSD.org . freebsd-libs-10.1~svn273304/lib/libelf/gelf_shdr.c0000644000000000000000000000662011421533314016377 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" Elf32_Shdr * elf32_getshdr(Elf_Scn *s) { return (_libelf_getshdr(s, ELFCLASS32)); } Elf64_Shdr * elf64_getshdr(Elf_Scn *s) { return (_libelf_getshdr(s, ELFCLASS64)); } GElf_Shdr * gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) { int ec; void *sh; Elf32_Shdr *sh32; Elf64_Shdr *sh64; if (d == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) return (NULL); ec = s->s_elf->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) { sh32 = (Elf32_Shdr *) sh; d->sh_name = sh32->sh_name; d->sh_type = sh32->sh_type; d->sh_flags = (Elf64_Xword) sh32->sh_flags; d->sh_addr = (Elf64_Addr) sh32->sh_addr; d->sh_offset = (Elf64_Off) sh32->sh_offset; d->sh_size = (Elf64_Xword) sh32->sh_size; d->sh_link = sh32->sh_link; d->sh_info = sh32->sh_info; d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; } else { sh64 = (Elf64_Shdr *) sh; *d = *sh64; } return (d); } int gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s) { int ec; Elf *e; Elf32_Shdr *sh32; if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (e->e_cmd == ELF_C_READ) { LIBELF_SET_ERROR(MODE, 0); return (0); } (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); if (ec == ELFCLASS64) { scn->s_shdr.s_shdr64 = *s; return (1); } sh32 = &scn->s_shdr.s_shdr32; sh32->sh_name = s->sh_name; sh32->sh_type = s->sh_type; LIBELF_COPY_U32(sh32, s, sh_flags); LIBELF_COPY_U32(sh32, s, sh_addr); LIBELF_COPY_U32(sh32, s, sh_offset); LIBELF_COPY_U32(sh32, s, sh_size); sh32->sh_link = s->sh_link; sh32->sh_info = s->sh_info; LIBELF_COPY_U32(sh32, s, sh_addralign); LIBELF_COPY_U32(sh32, s, sh_entsize); return (1); } freebsd-libs-10.1~svn273304/lib/libelf/elf_strptr.c0000644000000000000000000000707111015471710016627 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" /* * Convert an ELF section#,offset pair to a string pointer. */ char * elf_strptr(Elf *e, size_t scndx, size_t offset) { Elf_Scn *s; Elf_Data *d; size_t alignment, count; GElf_Shdr shdr; if (e == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((s = elf_getscn(e, scndx)) == NULL || gelf_getshdr(s, &shdr) == NULL) return (NULL); if (/*shdr.sh_type != SHT_STRTAB || */ offset >= shdr.sh_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } d = NULL; if (e->e_flags & ELF_F_LAYOUT) { /* * The application is taking responsibility for the * ELF object's layout, so we can directly translate * an offset to a `char *' address using the `d_off' * members of Elf_Data descriptors. */ while ((d = elf_getdata(s, d)) != NULL) { if (d->d_buf == 0 || d->d_size == 0) continue; if (d->d_type != ELF_T_BYTE) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } if (offset >= d->d_off && offset < d->d_off + d->d_size) return ((char *) d->d_buf + offset - d->d_off); } } else { /* * Otherwise, the `d_off' members are not useable and * we need to compute offsets ourselves, taking into * account 'holes' in coverage of the section introduced * by alignment requirements. */ count = (size_t) 0; /* cumulative count of bytes seen */ while ((d = elf_getdata(s, d)) != NULL && count <= offset) { if (d->d_buf == NULL || d->d_size == 0) continue; if (d->d_type != ELF_T_BYTE) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } if ((alignment = d->d_align) > 1) { if ((alignment & (alignment - 1)) != 0) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } count = roundup2(count, alignment); } if (offset < count) { /* offset starts in the 'hole' */ LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (offset < count + d->d_size) { if (d->d_buf != NULL) return ((char *) d->d_buf + offset - count); LIBELF_SET_ERROR(DATA, 0); return (NULL); } count += d->d_size; } } LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_syminfo.c0000644000000000000000000000716310541424661017134 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" #if __FreeBSD_version >= 700025 GElf_Syminfo * gelf_getsyminfo(Elf_Data *d, int ndx, GElf_Syminfo *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Syminfo *syminfo32; Elf64_Syminfo *syminfo64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx; dst->si_boundto = syminfo32->si_boundto; dst->si_flags = syminfo32->si_flags; } else { syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx; *dst = *syminfo64; } return (dst); } int gelf_update_syminfo(Elf_Data *d, int ndx, GElf_Syminfo *gs) { int ec; Elf *e; Elf_Scn *scn; Elf32_Syminfo *syminfo32; Elf64_Syminfo *syminfo64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || gs == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx; syminfo32->si_boundto = gs->si_boundto; syminfo32->si_flags = gs->si_flags; } else { syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx; *syminfo64 = *gs; } return (1); } #endif /* __FreeBSD_version >= 700025 */ freebsd-libs-10.1~svn273304/lib/libelf/gelf_getrela.30000644000000000000000000000663311361411226017006 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETRELA 3 .Os .Sh NAME .Nm gelf_getrela , .Nm gelf_update_rela .Nd read and update ELF relocation entries with addends .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Rela *" .Fn gelf_getrela "Elf_Data *data" "int ndx" "GElf_Rela *rela" .Ft int .Fn gelf_update_rela "Elf_Data *data" "int ndx" "GElf_Rela *rela" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Rela or .Vt Elf64_Rela structures in an ELF object. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_RELA . Argument .Ar ndx is the index of the entry being retrieved or updated. The class-independent .Vt GElf_Rela structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getrela retrieves the class-dependent entry at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar rela after translation to class-independent form. .Pp Function .Fn gelf_update_rela converts the class-independent entry pointed to by argument .Ar rela to class-dependent form, and writes it to the entry at index .Ar ndx in the data buffer described by argument .Ar data . Function .Fn gelf_update_rela signals an error if any of the values in the class-independent representation exceeds the representable limits of the target type. .Sh RETURN VALUES Function .Fn gelf_getrela returns the value of argument .Ar rela if successful, or NULL in case of an error. Function .Fn gelf_update_rela returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar rela were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of entries in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section of type .Dv SHT_RELA . .It Bq Er ELF_E_RANGE A value was not representable in the target type. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_cntl.30000644000000000000000000000610311533536731016156 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 9, 2006 .Dt ELF_CNTL 3 .Os .Sh NAME .Nm elf_cntl .Nd control an elf file descriptor .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_cntl "Elf *elf" "Elf_Cmd cmd" .Sh DESCRIPTION Function .Fn elf_cntl controls the ELF library's subsequent use of the file descriptor used to create ELF descriptor .Ar elf . .Pp Argument .Ar cmd informs the library of the action to be taken: .Bl -tag -width "ELF_C_FDDONE" .It Dv ELF_C_FDDONE This value instructs the ELF library not to perform any further I/O on the file descriptor associated with argument .Ar elf . For ELF descriptors opened with mode .Ar ELF_C_WRITE or .Ar ELF_C_RDWR subsequent .Fn elf_update operations on the descriptor will fail. .It Dv ELF_C_FDREAD This value instructs the ELF library to read in all necessary data associated with ELF descriptor .Ar elf into memory so that the underlying file descriptor can be safely closed with command .Dv ELF_C_FDDONE . .El .Pp Argument .Ar elf must be an ELF descriptor associated with a file system object (e.g., an .Xr ar 1 archive, an ELF file, or other data file). .Sh IMPLEMENTATION NOTES Due to use of .Xr mmap 2 internally, this function is a no-op for ELF objects opened in .Dv ELF_C_READ mode. .Sh RETURN VALUES Function .Fn elf_cntl returns 0 on success, or -1 if an error was detected. .Sh ERRORS .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARCHIVE Argument .Ar elf is a descriptor for an archive member. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar cmd was not recognized. .It Bq Er ELF_E_MODE An .Dv ELF_C_FDREAD operation was requested on an ELF descriptor opened for writing. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_end 3 , .Xr elf_next 3 , .Xr elf_update 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_getdyn.30000644000000000000000000000662511361411226016656 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETDYN 3 .Os .Sh NAME .Nm gelf_getdyn , .Nm gelf_update_dyn .Nd read and update ELF dynamic entries .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Dyn *" .Fn gelf_getdyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" .Ft int .Fn gelf_update_dyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Dyn or .Vt Elf64_Dyn information in the .Sy dynamic table of an ELF object. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_DYNAMIC . Argument .Ar ndx is the index of the entry being retrieved or updated. The class-independent .Vt GElf_Dyn structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getdyn retrieves the class-dependent entry at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar dyn after translation to class-independent form. .Pp Function .Fn gelf_update_dyn converts the class-independent entry pointed to by argument .Ar dyn to class-dependent form, and writes it to the entry at index .Ar ndx in the data buffer described by argument .Ar data . Function .Fn gelf_update_dyn signals an error if any of the values in the class-independent representation exceeds the representable limits of the target type. .Sh RETURN VALUES Function .Fn gelf_getdyn returns the value of argument .Ar dyn if successful, or NULL in case of an error. Function .Fn gelf_update_dyn returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar dyn were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of entries in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section of type .Dv SHT_DYNAMIC . .It Bq Er ELF_E_RANGE A value was not representable in the target type. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_scn.c0000644000000000000000000001315011421545376016062 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "_libelf.h" /* * Load an ELF section table and create a list of Elf_Scn structures. */ int _libelf_load_scn(Elf *e, void *ehdr) { int ec, swapbytes; size_t fsz, i, shnum; uint64_t shoff; char *src; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; Elf_Scn *scn; int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); assert(e != NULL); assert(ehdr != NULL); assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); #define CHECK_EHDR(E,EH) do { \ if (fsz != (EH)->e_shentsize || \ shoff + fsz * shnum > e->e_rawsize) { \ LIBELF_SET_ERROR(HEADER, 0); \ return (0); \ } \ } while (0) ec = e->e_class; fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); assert(fsz > 0); shnum = e->e_u.e_elf.e_nscn; if (ec == ELFCLASS32) { eh32 = (Elf32_Ehdr *) ehdr; shoff = (uint64_t) eh32->e_shoff; CHECK_EHDR(e, eh32); } else { eh64 = (Elf64_Ehdr *) ehdr; shoff = eh64->e_shoff; CHECK_EHDR(e, eh64); } xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); src = e->e_rawfile + shoff; /* * If the file is using extended numbering then section #0 * would have already been read in. */ i = 0; if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); i = 1; src += fsz; } for (; i < shnum; i++, src += fsz) { if ((scn = _libelf_allocate_scn(e, i)) == NULL) return (0); (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, (size_t) 1, swapbytes); if (ec == ELFCLASS32) { scn->s_offset = scn->s_rawoff = scn->s_shdr.s_shdr32.sh_offset; scn->s_size = scn->s_shdr.s_shdr32.sh_size; } else { scn->s_offset = scn->s_rawoff = scn->s_shdr.s_shdr64.sh_offset; scn->s_size = scn->s_shdr.s_shdr64.sh_size; } } e->e_flags |= LIBELF_F_SHDRS_LOADED; return (1); } Elf_Scn * elf_getscn(Elf *e, size_t index) { int ec; void *ehdr; Elf_Scn *s; if (e == NULL || e->e_kind != ELF_K_ELF || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (NULL); if (e->e_cmd != ELF_C_WRITE && (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && _libelf_load_scn(e, ehdr) == 0) return (NULL); STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) if (s->s_ndx == index) return (s); LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } size_t elf_ndxscn(Elf_Scn *s) { if (s == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (SHN_UNDEF); } return (s->s_ndx); } Elf_Scn * elf_newscn(Elf *e) { int ec; void *ehdr; Elf_Scn *scn; if (e == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { LIBELF_SET_ERROR(CLASS, 0); return (NULL); } if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (NULL); /* * The application may be asking for a new section descriptor * on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We * need to bring in the existing section information before * appending a new one to the list. * * Per the ELF(3) API, an application is allowed to open a * file using ELF_C_READ, mess with its internal structure and * use elf_update(...,ELF_C_NULL) to compute its new layout. */ if (e->e_cmd != ELF_C_WRITE && (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && _libelf_load_scn(e, ehdr) == 0) return (NULL); if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { assert(e->e_u.e_elf.e_nscn == 0); if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == NULL) return (NULL); e->e_u.e_elf.e_nscn++; } assert(e->e_u.e_elf.e_nscn > 0); if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL) return (NULL); e->e_u.e_elf.e_nscn++; (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); return (scn); } Elf_Scn * elf_nextscn(Elf *e, Elf_Scn *s) { if (e == NULL || (e->e_kind != ELF_K_ELF) || (s && s->s_elf != e)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } return (s == NULL ? elf_getscn(e, (size_t) 1) : STAILQ_NEXT(s, s_next)); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_fsize.c0000644000000000000000000000366110525402563016566 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" size_t elf32_fsize(Elf_Type t, size_t c, unsigned int v) { return (_libelf_fsize(t, ELFCLASS32, v, c)); } size_t elf64_fsize(Elf_Type t, size_t c, unsigned int v) { return (_libelf_fsize(t, ELFCLASS64, v, c)); } size_t gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v) { if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64) return (_libelf_fsize(t, e->e_class, v, c)); LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } freebsd-libs-10.1~svn273304/lib/libelf/elf.30000644000000000000000000004143711762351436015150 0ustar .\" Copyright (c) 2006,2007 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd October 21, 2007 .Dt ELF 3 .Os .Sh NAME .Nm elf .Nd API for manipulating ELF objects .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Sh DESCRIPTION The .Lb libelf provides functions that allow an application to read and manipulate ELF object files, and to read .Xr ar 1 archives. The library allows the manipulation of ELF objects in a byte ordering and word-size independent way, allowing an application to read and create ELF objects for 32 and 64 bit architectures and for little- and big-endian machines. The library is capable of processing ELF objects that use extended section numbering. .Pp This manual page serves to provide an overview of the functionality in the ELF library. Further information may found in the manual pages for individual .Xr ELF 3 functions that comprise the library. .Ss ELF Concepts As described in .Xr elf 5 , ELF files contain several data structures that are laid out in a specific way. ELF files begin with an .Dq Executable Header , and may contain an optional .Dq Program Header Table , and optional data in the form of ELF .Dq sections . A .Dq Section Header Table describes the content of the data in these sections. .Pp ELF objects have an associated .Dq "ELF class" which denotes the natural machine word size for the architecture the object is associated with. Objects for 32 bit architectures have an ELF class of .Dv ELFCLASS32 . Objects for 64 bit architectures have an ELF class of .Dv ELFCLASS64 . .Pp ELF objects also have an associated .Dq endianness which denotes the endianness of the machine architecture associated with the object. This may be .Dv ELFDATA2LSB for little-endian architectures and .Dv ELFDATA2MSB for big-endian architectures. .Pp ELF objects are also associated with an API version number. This version number determines the layout of the individual components of an ELF file and the semantics associated with these. .Ss Data Representation And Translation The .Xr ELF 3 library distinguishes between .Dq native representations of ELF data structures and their .Dq file representations. .Pp An application would work with ELF data in its .Dq native representation, i.e., using the native byteorder and alignment mandated by the processor the application is running on. The .Dq file representation of the same data could use a different byte ordering and follow different constraints on object alignment than these native constraints. .Pp Accordingly, the .Xr ELF 3 library offers translation facilities .Po .Xr elf32_xlatetof 3 , .Xr elf32_xlatetom 3 , .Xr elf64_xlatetof 3 and .Xr elf64_xlatetom 3 .Pc to and from these representations and also provides higher-level APIs that retrieve and store data from the ELF object in a transparent manner. .Ss Library Working Version Conceptually, there are three version numbers associated with an application using the ELF library to manipulate ELF objects: .Bl -bullet -compact -offset indent .It The ELF version that the application was compiled against. This version determines the ABI expected by the application. .It The ELF version of the ELF object being manipulated by the application through the ELF library. .It The ELF version (or set of versions) supported by the ELF library itself. .El .Pp In order to facilitate working with ELF objects of differing versions, the ELF library requires the application to call the .Fn elf_version function before invoking many of its operations, in order to inform the library of the application's desired working version. .Pp In the current implementation, all three versions have to be .Dv EV_CURRENT . .Ss Namespace use The ELF library uses the following prefixes: .Bl -tag -width "ELF_F_*" .It elf_* Used for class-independent functions. .It elf32_* Used for functions working with 32 bit ELF objects. .It elf64_* Used for functions working with 64 bit ELF objects. .It Elf_* Used for class-independent data types. .It ELF_C_* Used for command values used in a few functions. These symbols are defined as members of the .Vt Elf_Cmd enumeration. .It ELF_E_* Used for error numbers. .It ELF_F_* Used for flags. .It ELF_K_* These constants define the kind of file associated with an ELF descriptor. See .Xr elf_kind 3 . The symbols are defined by the .Vt Elf_Kind enumeration. .It ELF_T_* These values are defined by the .Vt Elf_Type enumeration, and denote the types of ELF data structures that can be present in an ELF object. .El .Ss Descriptors Applications communicate with the library using descriptors. These are: .Bl -tag -width ".Vt Elf_Data" .It Vt Elf An .Vt Elf descriptor represents an ELF object or an .Xr ar 1 archive. It is allocated using one of the .Fn elf_begin or .Fn elf_memory functions. An .Vt Elf descriptor can be used to read and write data to an ELF file. An .Vt Elf descriptor can be associated with zero or more .Vt Elf_Scn section descriptors. .Pp Given an ELF descriptor, the application may retrieve the ELF object's class-dependent .Dq "Executable Header" structures using the .Fn elf32_getehdr or .Fn elf64_getehdr functions. A new Ehdr structure may be allocated using the .Fn elf64_newehdr or .Fn elf64_newehdr functions. .Pp The .Dq "Program Header Table" associated with an ELF descriptor may be allocated using the .Fn elf32_getphdr or .Fn elf64_getphdr functions. A new program header table may be allocated or an existing table resized using the .Fn elf32_newphdr or .Fn elf64_newphdr functions. .Pp The .Vt Elf structure is opaque and has no members visible to the application. .\" TODO describe the Elf_Arhdr and Elf_Arsym structures. .It Vt Elf_Data An .Vt Elf_Data data structure describes an individual chunk of a ELF file as represented in memory. It has the following application visible members: .Bl -tag -width ".Vt unsigned int d_version" -compact .It Vt "uint64_t d_align" The in-file alignment of the data buffer within its containing ELF section. This value must be a power of two. .It Vt "uint64_t d_off" The offset with the containing section where this descriptors data would be placed. This field will be computed by the library unless the application requests full control of the ELF object's layout. .It Vt "uint64_t d_size" The number of bytes of data in this descriptor. .It Vt "void *d_buf" A pointer to data in memory. .It Vt "Elf_Type d_type" The ELF type (see below) of the data in this descriptor. .It Vt "unsigned int d_version" The operating version for the data in this buffer. .El .Pp .Vt Elf_Data descriptors are usually associated with .Vt Elf_Scn descriptors. Existing data descriptors associated with an ELF section may be structures are retrieved using the .Fn elf_getdata function. The .Fn elf_newdata function may be used to attach new data descriptors to an ELF section. .It Vt Elf_Scn .Vt Elf_Scn descriptors represent a section in an ELF object. .Pp They are retrieved using the .Fn elf_getscn function. An application may iterate through the existing sections of an ELF object using the .Fn elf_nextscn function. New sections may be allocated using the .Fn elf_newscn function. .Pp The .Vt Elf_Scn descriptor is opaque and contains no application modifiable fields. .El .Ss Supported Elf Types The following ELF datatypes are supported by the library. .Pp .Bl -tag -width ".Dv ELF_T_SYMINFO" -compact .It Dv ELF_T_ADDR Machine addresses. .It Dv ELF_T_BYTE Byte data. The library will not attempt to translate byte data. .It Dv ELF_T_CAP Software and hardware capability records. .It Dv ELF_T_DYN Records used in a section of type .Dv SHT_DYNAMIC . .It Dv ELF_T_EHDR ELF executable header. .It Dv ELF_T_HALF 16-bit unsigned words. .It Dv ELF_T_LWORD 64 bit unsigned words. .It Dv ELF_T_MOVE ELF Move records. .\".It Dv ELF_T_MOVEP .\" As yet unsupported. .It Dv ELF_T_NOTE ELF Note structures. .It Dv ELF_T_OFF File offsets. .It Dv ELF_T_PHDR ELF program header table entries. .It Dv ELF_T_REL ELF relocation entries. .It Dv ELF_T_RELA ELF relocation entries with addends. .It Dv ELF_T_SHDR ELF section header entries. .It Dv ELF_T_SWORD Signed 32-bit words. .It Dv ELF_T_SXWORD Signed 64-bit words. .It Dv ELF_T_SYMINFO ELF symbol information. .It Dv ELF_T_SYM ELF symbol table entries. .It Dv ELF_T_VDEF Symbol version definition records. .It Dv ELF_T_VNEED Symbol version requirement records. .It Dv ELF_T_WORD Unsigned 32-bit words. .It Dv ELF_T_XWORD Unsigned 64-bit words. .El .Pp The symbol .Dv ELF_T_NUM denotes the number of Elf types known to the library. .Pp The following table shows the mapping between ELF section types defined in .Xr elf 5 and the types supported by the library. .Bl -column ".Dv SHT_PREINIT_ARRAY" ".Dv ELF_T_SYMINFO" .It Em Section Type Ta Em "Library Type" Ta Em Description .It Dv SHT_DYNAMIC Ta Dv ELF_T_DYN Ta Xo .Sq .dynamic section entries. .Xc .It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking. .It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers. .It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker. .It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes. .It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers. .It Dv SHT_NOBITS Ta Dv ELF_T_BYTE Ta Xo Empty sections. See .Xr elf 5 . .Xc .It Dv SHT_NOTE Ta Dv ELF_T_NOTE Ta ELF note records. .It Dv SHT_PREINIT_ARRAY Ta Dv ELF_T_ADDR Ta Pre-initialization function pointers. .It Dv SHT_PROGBITS Ta Dv ELF_T_BYTE Ta Machine code. .It Dv SHT_REL Ta Dv ELF_T_REL Ta ELF relocation records. .It Dv SHT_RELA Ta Dv ELF_T_RELA Ta Relocation records with addends. .It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables. .It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables. .It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering. .It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. .It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. .It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. .It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. .It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. .El .Ss Functional Grouping This section contains a brief overview of the available functionality in the ELF library. Each function listed here is described further in its own manual page. .Bl -tag -width 2n .It "Archive Access" .Bl -tag -width 17n -compact .It Fn elf_getarsym Retrieve the archive symbol table. .It Fn elf_getarhdr Retrieve the archive header for an object. .It Fn elf_getbase Retrieve the offset of a member inside an archive. .It Fn elf_next Iterate through an .Xr ar 1 archive. .It Fn elf_rand Random access inside an .Xr ar 1 archive. .El .It "Data Structures" .Bl -tag -width 17n -compact .It Fn elf_getdata Retrieve translated data for an ELF section. .It Fn elf_getscn Retrieve the section descriptor for a named section. .It Fn elf_ndxscn Retrieve the index for a section. .It Fn elf_newdata Add a new .Vt Elf_Data descriptor to an ELF section. .It Fn elf_newscn Add a new section descriptor to an ELF descriptor. .It Fn elf_nextscn Iterate through the sections in an ELF object. .It Fn elf_rawdata Retrieve untranslated data for an ELF sectino. .It Fn elf_rawfile Return a pointer to the untranslated file contents for an ELF object. .It Fn elf32_getehdr , Fn elf64_getehdr Retrieve the Executable Header in an ELF object. .It Fn elf32_getphdr , Fn elf64_getphdr Retrieve the Program Header Table in an ELF object. .It Fn elf32_getshdr , Fn elf64_getshdr Retrieve the ELF section header associated with an .Vt Elf_Scn descriptor. .It Fn elf32_newehdr , Fn elf64_newehdr Allocate an Executable Header in an ELF object. .It Fn elf32_newphdr , Fn elf64_newphdr Allocate or resize the Program Header Table in an ELF object. .El .It "Data Translation" .Bl -tag -width 17n -compact .It Fn elf32_xlatetof , Fn elf64_xlatetof Translate an ELF data structure from its native representation to its file representation. .It Fn elf32_xlatetom , Fn elf64_xlatetom Translate an ELF data structure from its file representation to a native representation. .El .It "Error Reporting" .Bl -tag -width 17n -compact .It Fn elf_errno Retrieve the current error. .It Fn elf_errmsg Retrieve a human readable description of the current error. .El .It "Initialization" .Bl -tag -width 17n -compact .It Fn elf_begin Opens an .Xr ar 1 archive or ELF object given a file descriptor. .It Fn elf_end Close an ELF descriptor and release all its resources. .It Fn elf_memory Opens an .Xr ar 1 archive or ELF object present in a memory area. .It Fn elf_version Sets the operating version. .El .It "IO Control" .Bl -tag -width 17n -compact .It Fn elf_cntl Manage the association between and ELF descriptor and its underlying file. .It Fn elf_flagdata Mark an .Vt Elf_Data descriptor as dirty. .It Fn elf_flagehdr Mark the ELF Executable Header in an ELF descriptor as dirty. .It Fn elf_flagphdr Mark the ELF Program Header Table in an ELF descriptor as dirty. .It Fn elf_flagscn Mark an .Vt Elf_Scn descriptor as dirty. .It Fn elf_flagshdr Mark an ELF Section Header as dirty. .It Fn elf_setshstrndx Set the index of the section name string table for the ELF object. .It Fn elf_update Recompute ELF object layout and optionally write the modified object back to the underlying file. .El .It "Queries" .Bl -tag -width 17n -compact .It Fn elf32_checksum , Fn elf64_checkum Compute checksum of an ELF object. .It Fn elf_getident Retrieve the identification bytes for an ELF object. .It Fn elf_getshnum Retrieve the number of sections in an ELF object. .It Fn elf_getshstrndx Retrieve the section index of the section name string table in an ELF object. .It Fn elf_hash Compute the ELF hash value of a string. .It Fn elf_kind Query the kind of object associated with an ELF descriptor. .It Fn elf32_fsize , Fn elf64_fsize Return the size of the file representation of an ELF type. .El .El .Ss Controlling ELF Object Layout In the usual mode of operation, library will compute section offsets and alignments based on the contents of an ELF descriptor's sections without need for further intervention by the application. .Pp However, if the application wishes to take complete charge of the layout of the ELF file, it may set the .Dv ELF_F_LAYOUT flag on an ELF descriptor using .Xr elf_flagelf 3 , following which the library will use the data offsets and alignments specified by the application when laying out the file. Application control of file layout is described further in the .Xr elf_update 3 manual page. .Pp Gaps in between sections will be filled with the fill character set by function .Fn elf_fill . .Ss Error Handling In case an error is encountered, these library functions set an internal error number and signal the presence of the error by returning an special return value. The application can check the current error number by calling .Xr elf_errno 3 . A human readable description of the recorded error is available by calling .Xr elf_errmsg 3 . .Ss Memory Management Rules The library keeps track of all .Vt Elf_Scn and .Vt Elf_Data descriptors associated with an ELF descriptor and recovers them when the descriptor is closed using .Xr elf_end 3 . Thus the application must not call .Xr free 3 on data structures allocated by the ELF library. .Pp Conversely the library will not free data that it has not allocated. As an example, an application may call .Xr elf_newdata 3 to allocate a new .Vt Elf_Data descriptor and can set the .Va d_off member of the descriptor to point to a region of memory allocated using .Xr malloc 3 . It is the applications responsibility to free this area, though the library will reclaim the space used by the .Vt Elf_Data descriptor itself. .Sh SEE ALSO .Xr gelf 3 , .Xr elf 5 .Sh HISTORY The original ELF(3) API was developed for Unix System V. The current implementation of the ELF(3) API appeared in .Fx 7.0 . .Sh AUTHORS The ELF library was written by .An "Joseph Koshy" .Aq jkoshy@FreeBSD.org . freebsd-libs-10.1~svn273304/lib/libelf/elf_getarhdr.c0000644000000000000000000000316610525402563017077 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" Elf_Arhdr * elf_getarhdr(Elf *e) { Elf_Arhdr *arh; if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((arh = e->e_arhdr) != NULL) return (arh); return (_libelf_ar_gethdr(e)); } freebsd-libs-10.1~svn273304/lib/libelf/elf_getshstrndx.30000644000000000000000000000552711733605744017607 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 5, 2009 .Dt ELF_GETSHSTRNDX 3 .Os .Sh NAME .Nm elf_getshstrndx , .Nm elf_setshstrndx .Nd retrieve/update the index of the section name string table .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_getshstrndx "Elf *elf" "size_t *ndxptr" .Ft int .Fn elf_setshstrndx "Elf *elf" "size_t ndx" .Sh DESCRIPTION Function .Fn elf_getshstrndx retrieves the section index of the string table containing section names from descriptor .Ar elf and stores it into the location pointed to by argument .Ar ndxptr . Function .Fn elf_getshstrndx is deprecated. Please use .Xr elf_getshdrstrndx 3 instead. .Pp Function .Fn elf_setshstrndx sets the index of the section name string table to argument .Ar ndx . .Pp These routines allow applications to process both normal ELF objects and ELF objects that use extended section numbering uniformly. .Sh RETURN VALUES These functions return a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not for an ELF file. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf lacks an ELF Executable header. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx contained a value in the reserved range of section indices. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getident 3 , .Xr elf_getphdrnum 3 , .Xr elf_getshdrnum 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_rawfile.c0000644000000000000000000000332410525402563016724 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" char * elf_rawfile(Elf *e, size_t *sz) { char *ptr; size_t size; size = e ? e->e_rawsize : 0; ptr = NULL; if (e == NULL) LIBELF_SET_ERROR(ARGUMENT, 0); else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE) LIBELF_SET_ERROR(SEQUENCE, 0); if (sz) *sz = size; return (ptr); } freebsd-libs-10.1~svn273304/lib/libelf/elf_getarhdr.30000644000000000000000000000571311361411226017012 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 15, 2006 .Dt ELF_GETARHDR 3 .Os .Sh NAME .Nm elf_getarhdr .Nd retrieve ar(1) header for an archive member .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf_Arhdr *" .Fn elf_getarhdr "Elf *elf" .Sh DESCRIPTION The .Fn elf_getarhdr function returns a pointer to an archive member header for a descriptor .Ar elf . This descriptor must have been returned by a prior call to .Xr elf_begin 3 , and must be a descriptor for a member inside an .Xr ar 1 archive. .Pp Structure .Vt Elf_Arhdr includes the following members: .Bl -tag -width indent .It Vt "char *" Va ar_name A pointer to a null terminated string containing the translated name of the archive member. .It Vt "char *" Va ar_rawname A pointer to a null terminated string containing the untranslated name for the archive member, including all .Xr ar 1 formatting characters and trailing white space. .It Vt time_t Va ar_date The timestamp associated with the member. .It Vt uid_t Va ar_uid The uid of the creator of the member. .It Vt gid_t Va ar_gid The gid of the creator of the member. .It Vt mode_t Va ar_mode The file mode of the member. .It Vt size_t Va ar_size The size of the member in bytes. .El .Sh RETURN VALUES This function returns a valid pointer to an .Vt Elf_Arhdr structure if successful, or NULL if an error is encountered. .Sh ERRORS Function .Fn elf_getarhdr may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for a member of an .Xr ar 1 archive. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_getarsym 3 , .Xr elf_memory 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getscn.30000644000000000000000000001007211361411226016467 0ustar .\" Copyright (c) 2006,2007 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd October 22, 2007 .Dt ELF_GETSCN 3 .Os .Sh NAME .Nm elf_getscn , .Nm elf_ndxscn , .Nm elf_newscn , .Nm elf_nextscn .Nd get/allocate section information for an ELF object .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf_Scn *" .Fn elf_getscn "Elf *elf" "size_t index" .Ft size_t .Fn elf_ndxscn "Elf_Scn *scn" .Ft "Elf_Scn *" .Fn elf_newscn "Elf *elf" .Ft "Elf_Scn *" .Fn elf_nextscn "Elf *elf" "Elf_Scn *scn" .Sh DESCRIPTION These functions are used to iterate through the sections associated with an ELF descriptor. .Pp Function .Fn elf_getscn will return a section descriptor for the section at index .Ar index in the object denoted by ELF descriptor .Ar elf . An error will be signalled if the specified section does not exist. .Pp Function .Fn elf_ndxscn returns the section table index associated with section descriptor .Ar scn . .Pp Function .Fn elf_newscn creates a new section and appends it to the list of sections associated with descriptor .Ar elf . The library will automatically increment the .Va e_shnum field of the ELF header associated with descriptor .Ar elf , and will set the .Dv ELF_F_DIRTY flag on the returned section descriptor. For ELF descriptors opened for writing, the ELF library will automatically create an empty section at index zero .Dv ( SHN_UNDEF ) on the first call to .Fn elf_newscn . .Pp Function .Fn elf_nextscn takes a section descriptor .Ar scn and returns a pointer to the section descriptor at the next higher index. Argument .Ar scn is allowed to be NULL, in which case this function will return a pointer to the section descriptor at index 1. If no further sections are present, function .Fn elf_nextscn will return a NULL pointer. .Sh RETURN VALUES Functions .Fn elf_getscn , .Fn elf_newscn and .Fn elf_nextscn return a valid pointer to a section descriptor if successful, or NULL if an error occurs. .Pp Function .Fn elf_ndxscn returns a valid section table index if successful, or .Dv SHN_UNDEF if an error occurs. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar elf or .Ar scn were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar index exceeded the current number of sections in the ELF object. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF file. .It Bq Er ELF_E_ARGUMENT Section descriptor .Ar scn was not associated with ELF descriptor .Ar elf . .It Bq Er ELF_E_CLASS Descriptor .Ar elf was of an unknown ELF class. .It Bq Er ELF_E_SECTION Argument .Ar elf specified extended section numbering in the ELF header with the section header at index .Dv SHN_UNDEF not being of type .Dv SHT_NULL . .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_flagdata 3 , .Xr elf_flagscn 3 , .Xr elf_getdata 3 , .Xr elf_getshdr 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getphdrnum.30000644000000000000000000000520711734141115017366 0ustar .\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 5, 2009 .Dt ELF_GETPHDRNUM 3 .Os .Sh NAME .Nm elf_getphdrnum .Nd return the number of program headers in an ELF file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_getphdrnum "Elf *elf" "size_t *phnum" .Sh DESCRIPTION Function .Fn elf_getphdrnum retrieves the number of ELF program headers associated with descriptor .Ar elf and stores it into the location pointed to by argument .Ar phnum . .Pp This routine allows applications to uniformly process both normal ELF objects and ELF objects that use extended numbering. .Sh RETURN VALUES Function .Fn elf_getphdrnum returns a zero value if successful, or -1 in case of an error. .Sh ERRORS Function .Fn elf_getphnum can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not for an ELF file. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf lacks an ELF Executable Header. .It Bq Er ELF_E_HEADER The ELF Executable Header associated with argument .Ar elf was corrupt. .It Bq Er ELF_E_SECTION The section header at index .Dv SHN_UNDEF was corrupt. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getident 3 , .Xr elf_getshdrnum 3 , .Xr elf_getshdrstrndx 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/libelf_extended.c0000644000000000000000000000634210543632736017574 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" /* * Retrieve section #0, allocating a new section if needed. */ static Elf_Scn * _libelf_getscn0(Elf *e) { Elf_Scn *s; if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) return (s); return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); } int _libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) { Elf_Scn *scn; if (shnum >= SHN_LORESERVE) { if ((scn = _libelf_getscn0(e)) == NULL) return (0); assert(scn->s_ndx == SHN_UNDEF); if (ec == ELFCLASS32) scn->s_shdr.s_shdr32.sh_size = shnum; else scn->s_shdr.s_shdr64.sh_size = shnum; (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); shnum = 0; } if (ec == ELFCLASS32) ((Elf32_Ehdr *) eh)->e_shnum = shnum; else ((Elf64_Ehdr *) eh)->e_shnum = shnum; return (1); } int _libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) { Elf_Scn *scn; if (shstrndx >= SHN_LORESERVE) { if ((scn = _libelf_getscn0(e)) == NULL) return (0); assert(scn->s_ndx == SHN_UNDEF); if (ec == ELFCLASS32) scn->s_shdr.s_shdr32.sh_link = shstrndx; else scn->s_shdr.s_shdr64.sh_link = shstrndx; (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); shstrndx = SHN_XINDEX; } if (ec == ELFCLASS32) ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; else ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; return (1); } int _libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) { Elf_Scn *scn; if (phnum >= PN_XNUM) { if ((scn = _libelf_getscn0(e)) == NULL) return (0); assert(scn->s_ndx == SHN_UNDEF); if (ec == ELFCLASS32) scn->s_shdr.s_shdr32.sh_info = phnum; else scn->s_shdr.s_shdr64.sh_info = phnum; (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); phnum = PN_XNUM; } if (ec == ELFCLASS32) ((Elf32_Ehdr *) eh)->e_phnum = phnum; else ((Elf64_Ehdr *) eh)->e_phnum = phnum; return (1); } freebsd-libs-10.1~svn273304/lib/libelf/libelf_fsize.m40000644000000000000000000001040611421547141017175 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #include #include #include "_libelf.h" /* * Create an array of file sizes from the elf_type definitions */ divert(-1) include(SRCDIR`/elf_types.m4') /* * Translations from structure definitions to the size of their file * representations. */ /* `Basic' types. */ define(`BYTE_SIZE', 1) define(`IDENT_SIZE', `EI_NIDENT') /* Types that have variable length. */ define(`GNUHASH_SIZE', 1) define(`NOTE_SIZE', 1) /* Currently unimplemented types. */ define(`MOVEP_SIZE', 0) /* Overrides for 32 bit types that do not exist. */ define(`XWORD_SIZE32', 0) define(`SXWORD_SIZE32', 0) /* * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. */ define(`FSZ32',`_FSZ32($1_DEF)') define(`_FSZ32', `ifelse($#,1,0, `_BSZ32($1)+_FSZ32(shift($@))')') define(`_BSZ32',`$2_SIZE32') define(`FSZ64',`_FSZ64($1_DEF)') define(`_FSZ64', `ifelse($#,1,0, `_BSZ64($1)+_FSZ64(shift($@))')') define(`_BSZ64',`$2_SIZE64') /* * DEFINE_ELF_FSIZES(TYPE,NAME) * * Shorthand for defining for 32 and 64 versions * of elf type TYPE. * * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit * sizes. * * Otherwise, look for a explicit 32/64 bit size definition for TYPE, * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there * is nothing further to do. * * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, * compute an expression that adds up the sizes of the structure's * constituents. * * If such a structure definition is not known, treat TYPE as a primitive * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its * file representation size. */ define(`DEFINE_ELF_FSIZE', `ifdef($1`_SIZE', `define($1_SIZE32,$1_SIZE) define($1_SIZE64,$1_SIZE)', `ifdef($1`_SIZE32',`', `ifdef(`Elf32_'$2`_DEF', `define($1_SIZE32,FSZ32(Elf32_$2))', `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') ifdef($1`_SIZE64',`', `ifdef(`Elf64_'$2`_DEF', `define($1_SIZE64,FSZ64(Elf64_$2))', `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') define(`DEFINE_ELF_FSIZES', `ifelse($#,1,`', `DEFINE_ELF_FSIZE($1) DEFINE_ELF_FSIZES(shift($@))')') DEFINE_ELF_FSIZES(ELF_TYPE_LIST) DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type define(`FSIZE', `#if __FreeBSD_version >= $3 [ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 }, #endif') define(`FSIZES', `ifelse($#,1,`', `FSIZE($1) FSIZES(shift($@))')') divert(0) struct fsize { size_t fsz32; size_t fsz64; }; static struct fsize fsize[ELF_T_NUM] = { FSIZES(ELF_TYPE_LIST) }; size_t _libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) { size_t sz; sz = 0; if (v != EV_CURRENT) LIBELF_SET_ERROR(VERSION, 0); else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) LIBELF_SET_ERROR(ARGUMENT, 0); else { sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; if (sz == 0) LIBELF_SET_ERROR(UNIMPL, 0); } return (sz*c); } freebsd-libs-10.1~svn273304/lib/libelf/elf_rawfile.30000644000000000000000000000453111361411226016640 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd July 3, 2006 .Dt ELF_RAWFILE 3 .Os .Sh NAME .Nm elf_rawfile .Nd return uninterpreted contents of an ELF file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft char * .Fn elf_rawfile "Elf *elf" "size_t *sz" .Sh DESCRIPTION Function .Fn elf_rawfile returns the uninterpreted contents of the file referenced by ELF descriptor .Ar elf . .Pp If argument .Ar sz is non-null, the function stores the file's size in bytes in the location to which it points. A value of zero is written to this location if an error is encountered. .Sh RETURN VALUES Function .Fn elf_rawfile returns a valid pointer if successful or NULL if an error occurs. .Sh ERRORS Function .Fn elf_rawfile may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_SEQUENCE Argument .Ar elf was opened for writing and function .Fn elf_rawfile was invoked before .Xr elf_update 3 . .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getident 3 , .Xr elf_kind 3 , .Xr elf_update 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_getphnum.30000644000000000000000000000535011733605744017053 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 5, 2009 .Dt ELF_GETPHNUM 3 .Os .Sh NAME .Nm elf_getphnum .Nd return the number of program headers in an ELF file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_getphnum "Elf *elf" "size_t *phnum" .Sh DESCRIPTION This function is deprecated. Please use function .Xr elf_getphdrnum 3 instead. .Pp Function .Fn elf_getphnum retrieves the number of ELF program headers associated with descriptor .Ar elf and stores it into the location pointed to by argument .Ar phnum . .Pp This routine allows applications to uniformly process both normal ELF objects and ELF objects that use extended numbering. .Sh RETURN VALUES Function .Fn elf_getphnum returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS Function .Fn elf_getphnum can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not for an ELF file. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf lacks an ELF Executable Header. .It Bq Er ELF_E_HEADER The ELF Executable Header associated with argument .Ar elf was corrupt. .It Bq Er ELF_E_SECTION The section header at index .Dv SHN_UNDEF was corrupt. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getident 3 , .Xr elf_getphdrnum 3 , .Xr elf_getshdrnum 3 , .Xr elf_getshdrstrndx 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_dyn.c0000644000000000000000000000664310525402563016243 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" GElf_Dyn * gelf_getdyn(Elf_Data *d, int ndx, GElf_Dyn *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Dyn *dyn32; Elf64_Dyn *dyn64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { dyn32 = (Elf32_Dyn *) d->d_buf + ndx; dst->d_tag = dyn32->d_tag; dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val; } else { dyn64 = (Elf64_Dyn *) d->d_buf + ndx; *dst = *dyn64; } return (dst); } int gelf_update_dyn(Elf_Data *d, int ndx, GElf_Dyn *ds) { int ec; Elf *e; Elf_Scn *scn; Elf32_Dyn *dyn32; Elf64_Dyn *dyn64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || ds == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { dyn32 = (Elf32_Dyn *) d->d_buf + ndx; LIBELF_COPY_S32(dyn32, ds, d_tag); LIBELF_COPY_U32(dyn32, ds, d_un.d_val); } else { dyn64 = (Elf64_Dyn *) d->d_buf + ndx; *dyn64 = *ds; } return (1); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_fsize.30000644000000000000000000000544211421547141016503 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd February 5, 2008 .Dt GELF_FSIZE 3 .Os .Sh NAME .Nm gelf_fsize , .Nm elf32_fsize , .Nm elf64_fsize .Nd return the size of a file type .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft size_t .Fn elf32_fsize "Elf_Type type" "size_t count" "unsigned int version" .Ft size_t .Fn elf64_fsize "Elf_Type type" "size_t count" "unsigned int version" .In gelf.h .Ft size_t .Fn gelf_fsize "Elf *elf" "Elf_Type type" "size_t count" "unsigned int version" .Sh DESCRIPTION These functions return the size in bytes of the file representation of .Ar count numbers of objects of ELF type .Ar type . For ELF types that are of variable length, these functions return a size of one byte. .Pp Functions .Fn elf32_fsize and .Fn elf64_fsize return sizes for files of class .Dv ELFCLASS32 and .Dv ELFCLASS64 respectively. Function .Fn gelf_fsize returns the size for the class of ELF descriptor .Ar elf . .Sh RETURN VALUES These functions return a non-zero value in case of success, or zero in case of an error. .Sh ERRORS These functions may fail with: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL in a call to .Fn gelf_fsize . .It Bq Er ELF_E_ARGUMENT ELF descriptor .Ar elf had an unknown ELF class. .It Bq Er ELF_E_ARGUMENT Argument .Ar type contained an illegal value. .It Bq Er ELF_E_UNIMPL Support for ELF type .Ar type has not been implemented. .It Bq Er ELF_E_VERSION Argument .Ar version is not a supported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/libelf_checksum.c0000644000000000000000000000542410543632736017576 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" static unsigned long _libelf_sum(unsigned long c, const unsigned char *s, size_t size) { if (s == NULL || size == 0) return (c); while (size--) c += *s++; return (c); } unsigned long _libelf_checksum(Elf *e, int elfclass) { size_t shn; Elf_Scn *scn; Elf_Data *d; unsigned long checksum; GElf_Ehdr eh; GElf_Shdr shdr; if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0L); } if (e->e_class != elfclass) { LIBELF_SET_ERROR(CLASS, 0); return (0L); } if (gelf_getehdr(e, &eh) == NULL) return (0); /* * Iterate over all sections in the ELF file, computing the * checksum along the way. * * The first section is always SHN_UNDEF and can be skipped. * Non-allocatable sections are skipped, as are sections that * could be affected by utilities such as strip(1). */ checksum = 0; for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) { if ((scn = elf_getscn(e, shn)) == NULL) return (0); if (gelf_getshdr(scn, &shdr) == NULL) return (0); if ((shdr.sh_flags & SHF_ALLOC) == 0 || shdr.sh_type == SHT_DYNAMIC || shdr.sh_type == SHT_DYNSYM) continue; d = NULL; while ((d = elf_rawdata(scn, d)) != NULL) checksum = _libelf_sum(checksum, (unsigned char *) d->d_buf, d->d_size); } /* * Return a 16-bit checksum compatible with Solaris. */ return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); } freebsd-libs-10.1~svn273304/lib/libelf/elf_end.c0000644000000000000000000000464610525402563016051 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" int elf_end(Elf *e) { Elf *sv; Elf_Scn *scn, *tscn; if (e == NULL || e->e_activations == 0) return (0); if (--e->e_activations > 0) return (e->e_activations); assert(e->e_activations == 0); while (e && e->e_activations == 0) { switch (e->e_kind) { case ELF_K_AR: /* * If we still have open child descriptors, we * need to defer reclaiming resources till all * the child descriptors for the archive are * closed. */ if (e->e_u.e_ar.e_nchildren > 0) return (0); break; case ELF_K_ELF: /* * Reclaim all section descriptors. */ STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) scn = _libelf_release_scn(scn); break; case ELF_K_NUM: assert(0); default: break; } if (e->e_flags & LIBELF_F_MMAP) (void) munmap(e->e_rawfile, e->e_rawsize); sv = e; if ((e = e->e_parent) != NULL) e->e_u.e_ar.e_nchildren--; sv = _libelf_release_elf(sv); } return (0); } freebsd-libs-10.1~svn273304/lib/libelf/elf_data.c0000644000000000000000000001426112110570041016173 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" Elf_Data * elf_getdata(Elf_Scn *s, Elf_Data *d) { Elf *e; size_t fsz, msz, count; int elfclass, elftype; unsigned int sh_type; uint64_t sh_align, sh_offset, sh_size; int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF || (d != NULL && s != d->d_scn)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) return (d); if (d != NULL) return (STAILQ_NEXT(d, d_next)); if (e->e_rawfile == NULL) { LIBELF_SET_ERROR(SEQUENCE, 0); return (NULL); } elfclass = e->e_class; assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); if (elfclass == ELFCLASS32) { sh_type = s->s_shdr.s_shdr32.sh_type; sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; } else { sh_type = s->s_shdr.s_shdr64.sh_type; sh_offset = s->s_shdr.s_shdr64.sh_offset; sh_size = s->s_shdr.s_shdr64.sh_size; sh_align = s->s_shdr.s_shdr64.sh_addralign; } if (sh_type == SHT_NULL) { LIBELF_SET_ERROR(SECTION, 0); return (NULL); } if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && sh_offset + sh_size > (uint64_t) e->e_rawsize)) { LIBELF_SET_ERROR(SECTION, 0); return (NULL); } if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) (elftype, (size_t) 1, e->e_version)) == 0) { LIBELF_SET_ERROR(UNIMPL, 0); return (NULL); } if (sh_size % fsz) { LIBELF_SET_ERROR(SECTION, 0); return (NULL); } count = sh_size / fsz; msz = _libelf_msize(elftype, elfclass, e->e_version); assert(msz > 0); if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); d->d_buf = NULL; d->d_off = 0; d->d_align = sh_align; d->d_size = msz * count; d->d_type = elftype; d->d_version = e->e_version; if (sh_type == SHT_NOBITS || sh_size == 0) { STAILQ_INSERT_TAIL(&s->s_data, d, d_next); return (d); } if ((d->d_buf = malloc(msz*count)) == NULL) { (void) _libelf_release_data(d); LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } d->d_flags |= LIBELF_F_MALLOCED; xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); if (!(*xlate)(d->d_buf, d->d_size, e->e_rawfile + sh_offset, count, e->e_byteorder != LIBELF_PRIVATE(byteorder))) { _libelf_release_data(d); LIBELF_SET_ERROR(DATA, 0); return (NULL); } STAILQ_INSERT_TAIL(&s->s_data, d, d_next); return (d); } Elf_Data * elf_newdata(Elf_Scn *s) { Elf *e; Elf_Data *d; if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } /* * elf_newdata() has to append a data descriptor, so * bring in existing section data if not already present. */ if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data)) if (elf_getdata(s, NULL) == NULL) return (NULL); if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); STAILQ_INSERT_TAIL(&s->s_data, d, d_next); d->d_align = 1; d->d_buf = NULL; d->d_off = (uint64_t) ~0; d->d_size = 0; d->d_type = ELF_T_BYTE; d->d_version = LIBELF_PRIVATE(version); (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); return (d); } /* * Retrieve a data descriptor for raw (untranslated) data for section * `s'. */ Elf_Data * elf_rawdata(Elf_Scn *s, Elf_Data *d) { Elf *e; int elf_class; uint32_t sh_type; uint64_t sh_align, sh_offset, sh_size; if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF || e->e_rawfile == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) return (d); if (d != NULL) return (STAILQ_NEXT(d, d_next)); elf_class = e->e_class; assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64); if (elf_class == ELFCLASS32) { sh_type = s->s_shdr.s_shdr32.sh_type; sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; } else { sh_type = s->s_shdr.s_shdr64.sh_type; sh_offset = s->s_shdr.s_shdr64.sh_offset; sh_size = s->s_shdr.s_shdr64.sh_size; sh_align = s->s_shdr.s_shdr64.sh_addralign; } if (sh_type == SHT_NULL) { LIBELF_SET_ERROR(SECTION, 0); return (NULL); } if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); d->d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : e->e_rawfile + sh_offset; d->d_off = 0; d->d_align = sh_align; d->d_size = sh_size; d->d_type = ELF_T_BYTE; d->d_version = e->e_version; STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); return (d); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_newphdr.30000644000000000000000000000703411361411226017026 0ustar .\" Copyright (c) 2006,2007 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd October 22, 2007 .Dt GELF_NEWPHDR 3 .Os .Sh NAME .Nm elf32_newphdr , .Nm elf64_newphdr , .Nm gelf_newphdr .Nd allocate an ELF program header table .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf32_Phdr *" .Fn elf32_newphdr "Elf *elf" "size_t count" .Ft "Elf64_Phdr *" .Fn elf64_newphdr "Elf *elf" "size_t count" .In gelf.h .Ft "void *" .Fn gelf_newphdr "Elf *elf" "size_t count" .Sh DESCRIPTION These functions allocate an ELF Program Header table for an ELF descriptor. .Vt Elf32_Phdr and .Vt Elf64_Phdr descriptors are described further in .Xr elf 5 . .Pp Functions .Fn elf32_newphdr and .Fn elf64_newphdr allocate a table of .Ar count .Vt Elf32_Phdr and .Vt Elf64_Phdr descriptors respectively, discarding any existing program header table already present in the ELF descriptor .Ar elf . A value of zero for argument .Ar count may be used to delete an existing program header table from an ELF descriptor. .Pp Function .Fn gelf_newphdr will return a table of .Vt Elf32_Phdr or .Vt Elf64_Phdr with .Ar count elements depending on the ELF class of ELF descriptor .Ar elf . .Pp The functions set the .Dv ELF_F_DIRTY flag on the program header table. All members of the returned array of Phdr structures will be initialized to zero. .Pp After a successful call to these functions, the pointer returned by a prior call to .Fn elf32_getphdr or .Fn elf64_getphdr on the same descriptor .Ar elf will no longer be valid. .Sh RETURN VALUES The functions a valid pointer if successful, or NULL in case an error was encountered. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_CLASS ELF descriptor .Ar elf was of an unrecognized class. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected. .It Bq Er ELF_E_SEQUENCE An executable header was not allocated for ELF descriptor .Ar elf before using these APIs. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getphdr 3 , .Xr elf32_newehdr 3 , .Xr elf64_getphdr 3 , .Xr elf64_newehdr 3 , .Xr elf_flagphdr 3 , .Xr elf_getphnum 3 , .Xr gelf 3 , .Xr gelf_getphdr 3 , .Xr gelf_newehdr 3 , .Xr elf 5 freebsd-libs-10.1~svn273304/lib/libelf/gelf_checksum.30000644000000000000000000000635011361411226017161 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_CHECKSUM 3 .Os .Sh NAME .Nm elf32_checksum , .Nm elf64_checksum , .Nm gelf_checksum .Nd return the checksum of an ELF object .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft long .Fn elf32_checksum "Elf *elf" .Ft long .Fn elf64_checksum "Elf *elf" .In gelf.h .Ft long .Fn gelf_checksum "Elf *elf" .Sh DESCRIPTION These functions return a simple checksum of the ELF object described by their argument .Ar elf . The checksum is computed in way that allows its value to remain unchanged in presence of modifications to the ELF object by utilities like .Xr strip 1 . .Pp Function .Fn elf32_checksum returns a checksum for an ELF descriptor .Ar elf of class .Dv ELFCLASS32 . .Pp Function .Fn elf64_checksum returns a checksum for an ELF descriptor .Ar elf of class .Dv ELFCLASS64 . .Pp Function .Fn gelf_checksum provides a class-independent way retrieving the checksum for ELF object .Ar elf . .Sh RETURN VALUES These functions return the checksum of the ELF object, or zero in case an error was encountered. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF file. .It Bq Er ELF_E_ARGUMENT The ELF descriptor .Ar elf was not opened for reading or updating. .It Bq Er ELF_E_CLASS For functions .Fn elf32_checksum and .Fn elf64_checksum , ELF descriptor .Ar elf did not match the class of the called function. .It Bq Er ELF_E_HEADER The ELF object specified by argument .Ar elf had a malformed executable header. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected during processing. .It Bq Er ELF_E_SECTION The ELF object specified by argument .Ar elf contained a section with a malformed section header. .It Bq Er ELF_E_VERSION The ELF object was of an unsupported version. .El .Sh SEE ALSO .Xr strip 1 , .Xr elf 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_getclass.c0000644000000000000000000000276210525402563017254 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include "_libelf.h" int gelf_getclass(Elf *e) { return (e != NULL ? e->e_class : ELFCLASSNONE); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_getphdr.30000644000000000000000000000757111753270526017035 0ustar .\" Copyright (c) 2006,2007 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd October 21, 2007 .Dt GELF_GETPHDR 3 .Os .Sh NAME .Nm elf32_getphdr , .Nm elf64_getphdr , .Nm gelf_getphdr .Nd retrieve an ELF program header table .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf32_Phdr *" .Fn elf32_getphdr "Elf *elf" .Ft "Elf64_Phdr *" .Fn elf64_getphdr "Elf *elf" .In gelf.h .Ft "GElf_Phdr *" .Fn gelf_getphdr "Elf *elf" "int index" "GElf_Phdr *dst" .Sh DESCRIPTION These functions retrieve and translate ELF program header information from an ELF descriptor, if this information exists. .Pp Functions .Fn elf32_getphdr and .Fn elf64_getphdr return a pointer to an array of translated .Vt Elf32_Phdr and .Vt Elf64_Phdr descriptors respectively. These descriptors are described in .Xr elf 5 . The number of entries in this array may be determined using the .Xr elf_getphnum 3 function. .Pp Function .Fn gelf_getphdr will retrieve the program header table entry at index .Ar index from ELF descriptor .Ar elf . The translated program header table entry will be written to the address pointed to be argument .Ar dst . .Pp Applications may inform the library of modifications to a program header table entry by using the .Xr elf_flagphdr 3 API. Applications using the .Xr gelf 3 interface need to use the .Xr gelf_update_phdr 3 API to copy modifications to a program header entry back to the underlying ELF descriptor. .Sh RETURN VALUES The functions a valid pointer if successful, or NULL in case an error was encountered. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_ARGUMENT Argument .Ar dst was NULL. .It Bq Er ELF_E_ARGUMENT Index .Ar index was out of range. .It Bq Er ELF_E_CLASS The class of ELF descriptor .Ar elf did not match the expected class of the function being called. .It Bq Er ELF_E_HEADER ELF descriptor .Ar elf did not possess an executable header. .It Bq Er ELF_E_HEADER ELF descriptor .Ar elf had a corrupt executable header. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected. .It Bq Er ELF_E_SECTION The ELF descriptor in argument .Ar elf did not adhere to the conventions used for extended numbering. .It Bq Er ELF_VERSION ELF descriptor .Ar elf was of an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf32_newphdr 3 , .Xr elf64_getehdr 3 , .Xr elf64_newphdr 3 , .Xr elf_flagphdr 3 , .Xr elf_getphnum 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 , .Xr gelf_newphdr 3 , .Xr gelf_update_phdr 3 , .Xr elf 5 freebsd-libs-10.1~svn273304/lib/libelf/libelf_xlate.c0000644000000000000000000001014711421545376017106 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" /* * Translate to/from the file representation of ELF objects. * * Translation could potentially involve the following * transformations: * * - an endianness conversion, * - a change of layout, as the file representation of ELF objects * can differ from their in-memory representation. * - a change in representation due to a layout version change. */ Elf_Data * _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, int elfclass, int direction) { int byteswap; size_t cnt, dsz, fsz, msz; uintptr_t sb, se, db, de; if (encoding == ELFDATANONE) encoding = LIBELF_PRIVATE(byteorder); if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || dst == NULL || src == NULL || dst == src) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); if (dst->d_version != src->d_version) { LIBELF_SET_ERROR(UNIMPL, 0); return (NULL); } if (src->d_buf == NULL || dst->d_buf == NULL) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) (src->d_type, (size_t) 1, src->d_version)) == 0) return (NULL); msz = _libelf_msize(src->d_type, elfclass, src->d_version); assert(msz > 0); if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } /* * Determine the number of objects that need to be converted, and * the space required for the converted objects in the destination * buffer. */ if (direction == ELF_TOMEMORY) { cnt = src->d_size / fsz; dsz = cnt * msz; } else { cnt = src->d_size / msz; dsz = cnt * fsz; } if (dst->d_size < dsz) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } sb = (uintptr_t) src->d_buf; se = sb + src->d_size; db = (uintptr_t) dst->d_buf; de = db + dst->d_size; /* * Check for overlapping buffers. Note that db == sb is * allowed. */ if (db != sb && de > sb && se > db) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } if ((direction == ELF_TOMEMORY ? db : sb) % _libelf_malign(src->d_type, elfclass)) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } dst->d_type = src->d_type; dst->d_size = dsz; byteswap = encoding != LIBELF_PRIVATE(byteorder); if (src->d_size == 0 || (db == sb && !byteswap && fsz == msz)) return (dst); /* nothing more to do */ if (!(_libelf_get_translator(src->d_type, direction, elfclass)) (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } return (dst); } freebsd-libs-10.1~svn273304/lib/libelf/libelf_msize.m40000644000000000000000000000554311421542132017205 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include "_libelf.h" /* WARNING: GENERATED FROM __file__. */ struct msize { size_t msz32; size_t msz64; }; divert(-1) include(SRCDIR`/elf_types.m4') define(BYTE_SIZE, 1) define(GNUHASH_SIZE, 1) define(NOTE_SIZE, 1) /* * Unimplemented types. */ define(MOVEP_SIZE, 0) define(SXWORD_SIZE32, 0) define(XWORD_SIZE32, 0) define(`DEFINE_ELF_MSIZE', `ifdef($1`_SIZE', `define($1_SIZE32,$1_SIZE) define($1_SIZE64,$1_SIZE)', `ifdef($1`_SIZE32',`', `define($1_SIZE32,sizeof(Elf32_$2))') ifdef($1`_SIZE64',`', `define($1_SIZE64,sizeof(Elf64_$2))')')') define(`DEFINE_ELF_MSIZES', `ifelse($#,1,`', `DEFINE_ELF_MSIZE($1) DEFINE_ELF_MSIZES(shift($@))')') DEFINE_ELF_MSIZES(ELF_TYPE_LIST) define(`MSIZE', `#if __FreeBSD_version >= $3 [ELF_T_$1] = { .msz32 = $1_SIZE32, .msz64 = $1_SIZE64 }, #endif') define(`MSIZES', `ifelse($#,1,`', `MSIZE($1) MSIZES(shift($@))')') divert(0) static struct msize msize[ELF_T_NUM] = { MSIZES(ELF_TYPE_LIST) }; size_t _libelf_msize(Elf_Type t, int elfclass, unsigned int version) { size_t sz; assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); if (version != EV_CURRENT) { LIBELF_SET_ERROR(VERSION, 0); return (0); } sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; return (sz); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_checksum.c0000644000000000000000000000343510525402563017247 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include "_libelf.h" long elf32_checksum(Elf *e) { return (_libelf_checksum(e, ELFCLASS32)); } long elf64_checksum(Elf *e) { return (_libelf_checksum(e, ELFCLASS64)); } long gelf_checksum(Elf *e) { int ec; if (e == NULL || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0L); } return (_libelf_checksum(e, ec)); } freebsd-libs-10.1~svn273304/lib/libelf/gelf_getclass.30000644000000000000000000000371111361411226017162 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd July 3, 2006 .Dt GELF_GETCLASS 3 .Os .Sh NAME .Nm gelf_getclass .Nd retrieve the class of an ELF descriptor .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft int .Fn gelf_getclass "Elf *elf" .Sh DESCRIPTION Function .Fn gelf_getclass returns the ELF class of the descriptor supplied in argument .Ar elf . .Sh RETURN VALUES Function .Fn gelf_getclass will return one of .Dv ELFCLASS32 or .Dv ELFCLASS64 if the argument .Ar elf is a descriptor for an ELF file. The value .Dv ELFCLASSNONE is returned if argument .Ar elf was null, or if it was not a descriptor for an ELF file. .Sh SEE ALSO .Xr elf 3 , .Xr elf_kind 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/README0000644000000000000000000000064211130313462015151 0ustar # $FreeBSD$ # $NetBSD$ libelf: a BSD-licensed implementation of the ELF(3)/GELF(3) API. Documentation: * Manual page elf.3 contains an overview of the library. Other manual pages document individual APIs in the library. * A tutorial "libelf by Example" is available at: http://people.freebsd.org/~jkoshy/download/libelf/article.html For ongoing development please see http://elftoolchain.sourceforge.net/ freebsd-libs-10.1~svn273304/lib/libelf/gelf_getmove.30000644000000000000000000000666111361411226017032 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETMOVE 3 .Os .Sh NAME .Nm gelf_getmove , .Nm gelf_update_move .Nd read and update Elf Move information .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Move *" .Fn gelf_getmove "Elf_Data *data" "int ndx" "GElf_Move *move" .Ft int .Fn gelf_update_move "Elf_Data *data" "int ndx" "GElf_Move *move" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Move and .Vt Elf64_Move structures in an ELF object. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_SUNW_move . Argument .Ar ndx is the index of the move record being retrieved or updated. The class-independent .Vt GElf_Move structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getmove retrieves class-dependent move record at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar move after translation to class-independent form. .Pp Function .Fn gelf_update_move converts the class-independent move information pointed to by argument .Ar move to class-dependent form, and writes it to the move record at index .Ar ndx in the data buffer described by argument .Ar data . Function .Fn gelf_update_move signals an error if any of the values in the class-independent representation exceeds the representable limits of the target type. .Sh RETURN VALUES Function .Fn gelf_getmove returns the value of argument .Ar move if successful, or NULL in case of an error. Function .Fn gelf_update_move returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar move were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of records in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section containing move information. .It Bq Er ELF_E_RANGE A value was not representable in the target type. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_end.30000644000000000000000000000452711361411226015762 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd June 29, 2006 .Dt ELF_END 3 .Os .Sh NAME .Nm elf_end .Nd release an ELF descriptor .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_end "Elf *elf" .Sh DESCRIPTION Function .Fn elf_end is used to release the resources associated with an ELF descriptor pointed to by argument .Ar elf . This descriptor must have been allocated by a previous call to .Xr elf_begin 3 or .Xr elf_memory 3 . For programming convenience, a NULL value is permitted for argument .Ar elf . .Pp A call to .Fn elf_end decrements the activation count for descriptor .Ar elf by one. The resources associated with the descriptor are only released with its activation count goes to zero. .Pp Once function .Fn elf_end returns zero, the ELF descriptor .Ar elf will no longer be valid and should not be used further. .Sh RETURN VALUES Function .Fn elf_end returns the current value of the ELF descriptor .Ar elf Ap s activation count, or zero if argument .Ar elf was NULL. .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_memory 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/libelf_ehdr.c0000644000000000000000000001334711421545376016720 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" /* * Retrieve counts for sections, phdrs and the section string table index * from section header #0 of the ELF object. */ static int _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, uint16_t strndx) { Elf_Scn *scn; size_t fsz; int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); uint32_t shtype; assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); assert(fsz > 0); if (e->e_rawsize < shoff + fsz) { /* raw file too small */ LIBELF_SET_ERROR(HEADER, 0); return (0); } if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) return (0); xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), e->e_rawfile + shoff, (size_t) 1, e->e_byteorder != LIBELF_PRIVATE(byteorder)); #define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ scn->s_shdr.s_shdr64.M) if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { LIBELF_SET_ERROR(SECTION, 0); return (0); } e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : GET_SHDR_MEMBER(sh_info); e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : GET_SHDR_MEMBER(sh_link); #undef GET_SHDR_MEMBER return (1); } #define EHDR_INIT(E,SZ) do { \ Elf##SZ##_Ehdr *eh = (E); \ eh->e_ident[EI_MAG0] = ELFMAG0; \ eh->e_ident[EI_MAG1] = ELFMAG1; \ eh->e_ident[EI_MAG2] = ELFMAG2; \ eh->e_ident[EI_MAG3] = ELFMAG3; \ eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ eh->e_ident[EI_DATA] = ELFDATANONE; \ eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ eh->e_machine = EM_NONE; \ eh->e_type = ELF_K_NONE; \ eh->e_version = LIBELF_PRIVATE(version); \ } while (0) void * _libelf_ehdr(Elf *e, int ec, int allocate) { void *ehdr; size_t fsz, msz; uint16_t phnum, shnum, strndx; uint64_t shoff; int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (e == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (e->e_class != ELFCLASSNONE && e->e_class != ec) { LIBELF_SET_ERROR(CLASS, 0); return (NULL); } if (e->e_version != EV_CURRENT) { LIBELF_SET_ERROR(VERSION, 0); return (NULL); } if (e->e_class == ELFCLASSNONE) e->e_class = ec; if (ec == ELFCLASS32) ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; else ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; if (ehdr != NULL) /* already have a translated ehdr */ return (ehdr); fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); assert(fsz > 0); if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { LIBELF_SET_ERROR(HEADER, 0); return (NULL); } msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); assert(msz > 0); if ((ehdr = calloc((size_t) 1, msz)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } if (ec == ELFCLASS32) { e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; EHDR_INIT(ehdr,32); } else { e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; EHDR_INIT(ehdr,64); } if (allocate) e->e_flags |= ELF_F_DIRTY; if (e->e_cmd == ELF_C_WRITE) return (ehdr); xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, e->e_byteorder != LIBELF_PRIVATE(byteorder)); /* * If extended numbering is being used, read the correct * number of sections and program header entries. */ if (ec == ELFCLASS32) { phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; } else { phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; } if (shnum >= SHN_LORESERVE || (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || strndx == SHN_XINDEX))) { LIBELF_SET_ERROR(HEADER, 0); return (NULL); } if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ e->e_u.e_elf.e_nphdr = phnum; e->e_u.e_elf.e_nscn = shnum; e->e_u.e_elf.e_strndx = strndx; } else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) return (NULL); return (ehdr); } freebsd-libs-10.1~svn273304/lib/libelf/elf_getshnum.30000644000000000000000000000502511733605744017055 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 5, 2009 .Dt ELF_GETSHNUM 3 .Os .Sh NAME .Nm elf_getshnum .Nd return the number of sections in an ELF file .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft int .Fn elf_getshnum "Elf *elf" "size_t *shnum" .Sh DESCRIPTION This function is deprecated. Please use .Xr elf_getshdrnum 3 instead. .Pp Function .Fn elf_getshnum retrieves the number of ELF sections associated with descriptor .Ar elf and stores it into the location pointed to by argument .Ar shnum . .Pp This routine allows applications to uniformly process both normal ELF objects, and ELF objects that use extended section numbering. .Sh RETURN VALUES Function .Fn elf_getshnum returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS Function .Fn elf_getshnum can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT A NULL value was passed in for argument .Ar elf . .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not for an ELF file. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf lacks an ELF Executable header. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_getident 3 , .Xr elf_getphdrnum 3 , .Xr elf_getshdrstrndx 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 freebsd-libs-10.1~svn273304/lib/libelf/gelf_rel.c0000644000000000000000000000730010762445046016230 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "_libelf.h" GElf_Rel * gelf_getrel(Elf_Data *d, int ndx, GElf_Rel *dst) { int ec; Elf *e; Elf_Scn *scn; Elf32_Rel *rel32; Elf64_Rel *rel64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dst == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } msz = _libelf_msize(ELF_T_REL, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { rel32 = (Elf32_Rel *) d->d_buf + ndx; dst->r_offset = (Elf64_Addr) rel32->r_offset; dst->r_info = ELF64_R_INFO( (Elf64_Xword) ELF32_R_SYM(rel32->r_info), ELF32_R_TYPE(rel32->r_info)); } else { rel64 = (Elf64_Rel *) d->d_buf + ndx; *dst = *rel64; } return (dst); } int gelf_update_rel(Elf_Data *d, int ndx, GElf_Rel *dr) { int ec; Elf *e; Elf_Scn *scn; Elf32_Rel *rel32; Elf64_Rel *rel64; size_t msz; uint32_t sh_type; if (d == NULL || ndx < 0 || dr == NULL || (scn = d->d_scn) == NULL || (e = scn->s_elf) == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } ec = e->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) sh_type = scn->s_shdr.s_shdr32.sh_type; else sh_type = scn->s_shdr.s_shdr64.sh_type; if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } msz = _libelf_msize(ELF_T_REL, ec, e->e_version); assert(msz > 0); if (msz * ndx >= d->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { rel32 = (Elf32_Rel *) d->d_buf + ndx; LIBELF_COPY_U32(rel32, dr, r_offset); if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { LIBELF_SET_ERROR(RANGE, 0); return (0); } rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), ELF64_R_TYPE(dr->r_info)); } else { rel64 = (Elf64_Rel *) d->d_buf + ndx; *rel64 = *dr; } return (1); } freebsd-libs-10.1~svn273304/lib/libelf/elf_hash.30000644000000000000000000000412511361411226016131 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 15, 2006 .Dt ELF_HASH 3 .Os .Sh NAME .Nm elf_hash .Nd compute a hash value for a string .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "unsigned long" .Fn elf_hash "const char *name" .Sh DESCRIPTION Function .Fn elf_hash computes a portable hash value for the null terminated string pointed to by argument .Ar name . .Pp The hash value returned is will be identical across machines of different architectures. This allows hash tables to be built on one machine and correctly used on another of a different architecture. The hash value returned is also guaranteed .Em not to be the bit pattern of all ones (~0UL). .Sh IMPLEMENTATION NOTES The library internally uses unsigned 32 bit arithmetic to compute the hash value. .Sh SEE ALSO .Xr elf 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/elf_types.m40000644000000000000000000001543511421551222016534 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ /* * ELF types, defined in the "enum Elf_Type" API. * * The members of the list form a 3-tuple: (name, C-type-suffix, OSversion). * + `name' is an Elf_Type symbol without the `ELF_T_' prefix. * + `C-type-suffix' is the suffix for Elf32_ and Elf64_ type names. * + `version' is the OS version the symbol first appeared in. * * OS revisions of note are: * 600102 - The earliest (6.0-STABLE) version supported by this code. * 700009 - Symbol versioning and ELF64 type changes. * 700025 - More ELF types and the introduction of libelf. */ define(`ELF_TYPE_LIST', ``ADDR, Addr, 600102', `BYTE, Byte, 600102', `CAP, Cap, 700025', `DYN, Dyn, 600102', `EHDR, Ehdr, 600102', `GNUHASH, -, 800062', `HALF, Half, 600102', `LWORD, Lword, 700025', `MOVE, Move, 700025', `MOVEP, MoveP, 700025', `NOTE, Note, 600102', `OFF, Off, 600102', `PHDR, Phdr, 600102', `REL, Rel, 600102', `RELA, Rela, 600102', `SHDR, Shdr, 600102', `SWORD, Sword, 600102', `SXWORD, Sxword, 700009', `SYMINFO, Syminfo, 700025', `SYM, Sym, 600102', `VDEF, Verdef, 700009', `VNEED, Verneed, 700009', `WORD, Word, 600102', `XWORD, Xword, 700009', `NUM, _, _'') /* * DEFINE_STRUCT(NAME,MEMBERLIST...) * * Map a type name to its members. * * Each member-list element comprises of pairs of (field name, type), * in the sequence used in the file representation of `NAME'. * * Each member list element comprises a pair containing a field name * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. * * The last element of a member list is the null element: `_,_'. */ define(`DEFINE_STRUCT',`define(`$1_DEF',shift($@))dnl') DEFINE_STRUCT(`Elf32_Cap', ``c_tag, WORD', `c_un.c_val, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Cap', ``c_tag, XWORD', `c_un.c_val, XWORD', `_,_'') DEFINE_STRUCT(`Elf32_Dyn', ``d_tag, SWORD', `d_un.d_ptr, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Dyn', ``d_tag, SXWORD', `d_un.d_ptr, XWORD', `_,_'') DEFINE_STRUCT(`Elf32_Ehdr', ``e_ident, IDENT', `e_type, HALF', `e_machine, HALF', `e_version, WORD', `e_entry, ADDR', `e_phoff, OFF', `e_shoff, OFF', `e_flags, WORD', `e_ehsize, HALF', `e_phentsize, HALF', `e_phnum, HALF', `e_shentsize, HALF', `e_shnum, HALF', `e_shstrndx, HALF', `_,_'') DEFINE_STRUCT(`Elf64_Ehdr', ``e_ident, IDENT', `e_type, HALF', `e_machine, HALF', `e_version, WORD', `e_entry, ADDR', `e_phoff, OFF', `e_shoff, OFF', `e_flags, WORD', `e_ehsize, HALF', `e_phentsize, HALF', `e_phnum, HALF', `e_shentsize, HALF', `e_shnum, HALF', `e_shstrndx, HALF', `_,_'') DEFINE_STRUCT(`Elf32_Move', ``m_value, LWORD', `m_info, WORD', `m_poffset, WORD', `m_repeat, HALF', `m_stride, HALF', `_,_'') DEFINE_STRUCT(`Elf64_Move', ``m_value, LWORD', `m_info, XWORD', `m_poffset, XWORD', `m_repeat, HALF', `m_stride, HALF', `_,_'') DEFINE_STRUCT(`Elf32_Phdr', ``p_type, WORD', `p_offset, OFF', `p_vaddr, ADDR', `p_paddr, ADDR', `p_filesz, WORD', `p_memsz, WORD', `p_flags, WORD', `p_align, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Phdr', ``p_type, WORD', `p_flags, WORD', `p_offset, OFF', `p_vaddr, ADDR', `p_paddr, ADDR', `p_filesz, XWORD', `p_memsz, XWORD', `p_align, XWORD', `_,_'') DEFINE_STRUCT(`Elf32_Rel', ``r_offset, ADDR', `r_info, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Rel', ``r_offset, ADDR', `r_info, XWORD', `_,_'') DEFINE_STRUCT(`Elf32_Rela', ``r_offset, ADDR', `r_info, WORD', `r_addend, SWORD', `_,_'') DEFINE_STRUCT(`Elf64_Rela', ``r_offset, ADDR', `r_info, XWORD', `r_addend, SXWORD', `_,_'') DEFINE_STRUCT(`Elf32_Shdr', ``sh_name, WORD', `sh_type, WORD', `sh_flags, WORD', `sh_addr, ADDR', `sh_offset, OFF', `sh_size, WORD', `sh_link, WORD', `sh_info, WORD', `sh_addralign, WORD', `sh_entsize, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Shdr', ``sh_name, WORD', `sh_type, WORD', `sh_flags, XWORD', `sh_addr, ADDR', `sh_offset, OFF', `sh_size, XWORD', `sh_link, WORD', `sh_info, WORD', `sh_addralign, XWORD', `sh_entsize, XWORD', `_,_'') DEFINE_STRUCT(`Elf32_Sym', ``st_name, WORD', `st_value, ADDR', `st_size, WORD', `st_info, BYTE', `st_other, BYTE', `st_shndx, HALF', `_,_'') DEFINE_STRUCT(`Elf64_Sym', ``st_name, WORD', `st_info, BYTE', `st_other, BYTE', `st_shndx, HALF', `st_value, ADDR', `st_size, XWORD', `_,_'') DEFINE_STRUCT(`Elf32_Syminfo', ``si_boundto, HALF', `si_flags, HALF', `_,_'') DEFINE_STRUCT(`Elf64_Syminfo', ``si_boundto, HALF', `si_flags, HALF', `_,_'') DEFINE_STRUCT(`Elf32_Verdaux', ``vda_name, WORD', `vda_next, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Verdaux', ``vda_name, WORD', `vda_next, WORD', `_,_'') DEFINE_STRUCT(`Elf32_Verdef', ``vd_version, HALF', `vd_flags, HALF', `vd_ndx, HALF', `vd_cnt, HALF', `vd_hash, WORD', `vd_aux, WORD', `vd_next, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Verdef', ``vd_version, HALF', `vd_flags, HALF', `vd_ndx, HALF', `vd_cnt, HALF', `vd_hash, WORD', `vd_aux, WORD', `vd_next, WORD', `_,_'') DEFINE_STRUCT(`Elf32_Verneed', ``vn_version, HALF', `vn_cnt, HALF', `vn_file, WORD', `vn_aux, WORD', `vn_next, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Verneed', ``vn_version, HALF', `vn_cnt, HALF', `vn_file, WORD', `vn_aux, WORD', `vn_next, WORD', `_,_'') DEFINE_STRUCT(`Elf32_Vernaux', ``vna_hash, WORD', `vna_flags, HALF', `vna_other, HALF', `vna_name, WORD', `vna_next, WORD', `_,_'') DEFINE_STRUCT(`Elf64_Vernaux', ``vna_hash, WORD', `vna_flags, HALF', `vna_other, HALF', `vna_name, WORD', `vna_next, WORD', `_,_'') freebsd-libs-10.1~svn273304/lib/libelf/gelf_getehdr.30000644000000000000000000000666111361411226017006 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd December 16, 2006 .Dt GELF_GETEHDR 3 .Os .Sh NAME .Nm elf32_getehdr , .Nm elf64_getehdr , .Nm gelf_getehdr .Nd retrieve the object file header .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf32_Ehdr *" .Fn elf32_getehdr "Elf *elf" .Ft "Elf64_Ehdr *" .Fn elf64_getehdr "Elf *elf" .In gelf.h .Ft "GElf_Ehdr *" .Fn gelf_getehdr "Elf *elf" "GElf_Ehdr *dst" .Sh DESCRIPTION These functions retrieve the ELF object file header from the ELF descriptor .Ar elf and return a translated header descriptor to their callers. .Pp Functions .Fn elf32_getehdr and .Fn elf64_getehdr return a pointer to the appropriate class-specific header descriptor if it exists in the file referenced by descriptor .Ar elf . These functions return .Dv NULL if an ELF header was not found in file .Ar elf . .Pp Function .Fn gelf_getehdr stores a translated copy of the header for ELF file .Ar elf into the descriptor pointed to by argument .Ar dst . It returns argument .Ar dst if successful or .Dv NULL in case of failure. .Sh RETURN VALUES These functions return a pointer to a translated header descriptor if successful, or NULL on failure. .Sh ERRORS These functions can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT The argument .Ar elf was null. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF file. .It Bq Er ELF_E_ARGUMENT The elf class of descriptor .Ar elf was not recognized. .It Bq Er ELF_E_ARGUMENT Argument .Ar dst was null. .It Bq Er ELF_E_CLASS The ELF class of descriptor .Ar elf did not match that of the API function being called. .It Bq Er ELF_E_HEADER ELF descriptor .Ar elf does not have an associated header. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected during execution. .It Bq Er ELF_E_SECTION The ELF descriptor in argument .Ar elf did not adhere to the conventions used for extended numbering. .It Bq Er ELF_E_VERSION The ELF descriptor .Ar elf had an unsupported ELF version number. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_newehdr 3 , .Xr elf64_newehdr 3 , .Xr elf_flagehdr 3 , .Xr elf_getident 3 , .Xr gelf 3 , .Xr gelf_newehdr 3 , .Xr elf 5 freebsd-libs-10.1~svn273304/lib/libelf/gelf_newehdr.30000644000000000000000000001150311753270526017022 0ustar .\" Copyright (c) 2006,2007 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd October 22, 2007 .Dt GELF_NEWEHDR 3 .Os .Sh NAME .Nm elf32_newehdr , .Nm elf64_newehdr , .Nm gelf_newehdr .Nd retrieve or allocate the object file header .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf32_Ehdr *" .Fn elf32_newehdr "Elf *elf" .Ft "Elf64_Ehdr *" .Fn elf64_newehdr "Elf *elf" .In gelf.h .Ft "void *" .Fn gelf_newehdr "Elf *elf" "int elfclass" .Sh DESCRIPTION These functions retrieve the ELF header from the ELF descriptor .Ar elf , allocating a new header if needed. File data structures are translated to their in-memory representations as described in .Xr elf 3 . .Pp Function .Fn elf32_newehdr returns a pointer to a 32 bit .Vt Elf32_Ehdr structure. Function .Fn elf64_newehdr returns a pointer to a 64 bit .Vt Elf64_Ehdr structure. .Pp When argument .Ar elfclass has value .Dv ELFCLASS32 , function .Fn gelf_newehdr returns the value returned by .Fn elf32_newehdr "elf" . When argument .Ar elfclass has value .Dv ELFCLASS64 it returns the value returned by .Fn elf64_newehdr "elf" . .Pp If a fresh header structure is allocated, the members of the structure are initialized as follows: .Bl -tag -width indent .It Va "e_ident[EI_MAG0..EI_MAG3]" Identification bytes at offsets .Dv EI_MAG0 , .Dv EI_MAG1 , .Dv EI_MAG2 and .Dv EI_MAG3 are set to the ELF signature. .It Va "e_ident[EI_CLASS]" The identification byte at offset .Dv EI_CLASS is set to the ELF class associated with the function being called or to argument .Ar elfclass for function .Fn gelf_newehdr . .It Va "e_ident[EI_DATA]" The identification byte at offset .Dv EI_DATA is set to .Dv ELFDATANONE . .It Va "e_ident[EI_VERSION]" The identification byte at offset .Dv EI_VERSION is set to the ELF library's operating version set by a prior call to .Xr elf_version 3 . .It Va e_machine is set to .Dv EM_NONE . .It Va e_type is set to .Dv ELF_K_NONE . .It Va e_version is set to the ELF library's operating version set by a prior call to .Xr elf_version 3 . .El .Pp Other members of the header are set to zero. The application is responsible for changing these values as needed before calling .Fn elf_update . .Pp If successful, these three functions set the .Dv ELF_F_DIRTY flag on ELF descriptor .Ar elf . .Sh RETURN VALUES These functions return a pointer to a translated header descriptor if successful, or NULL on failure. .Sh ERRORS These functions can fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT The argument .Ar elf was null. .It Bq Er ELF_E_ARGUMENT Argument .Ar elf was not a descriptor for an ELF object. .It Bq Er ELF_E_ARGUMENT Argument .Ar elfclass had an unsupported value. .It Bq Er ELF_E_ARGUMENT The class of the ELF descriptor .Ar elf did not match that of the requested operation. .It Bq Er ELF_E_ARGUMENT For function .Fn gelf_newehdr , the class of argument .Ar elf was not .Dv ELFCLASSNONE and did not match the argument .Ar elfclass . .It Bq Er ELF_E_CLASS The ELF class of descriptor .Ar elf did not match that of the API function being called. .It Bq Er ELF_E_HEADER A malformed ELF header was detected. .It Bq Er ELF_E_RESOURCE An out of memory condition was detected during execution. .It Bq Er ELF_E_SECTION The ELF descriptor in argument .Ar elf did not adhere to the conventions used for extended numbering. .It Bq Er ELF_E_VERSION The ELF descriptor .Ar elf had an unsupported ELF version number. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf32_getehdr 3 , .Xr elf64_getehdr 3 , .Xr elf_flagdata 3 , .Xr elf_getident 3 , .Xr elf_update 3 , .Xr elf_version 3 , .Xr gelf 3 , .Xr gelf_getehdr 3 , .Xr elf 5 freebsd-libs-10.1~svn273304/lib/libelf/elf_hash.c0000644000000000000000000000343410525402563016220 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include /* * This elf_hash function is defined by the System V ABI. It must be * kept compatible with "src/libexec/rtld-elf/rtld.c". */ unsigned long elf_hash(const char *name) { unsigned long h, t; const unsigned char *s; s = (const unsigned char *) name; h = t = 0; for (; *s != '\0'; h = h & ~t) { h = (h << 4) + *s++; t = h & 0xF0000000UL; if (t) h ^= t >> 24; } return (h); } freebsd-libs-10.1~svn273304/lib/libelf/Makefile0000644000000000000000000001046312003543520015733 0ustar # $FreeBSD$ LIB= elf SRCS= elf_begin.c \ elf_cntl.c \ elf_end.c elf_errmsg.c elf_errno.c \ elf_data.c \ elf_fill.c \ elf_flag.c \ elf_getarhdr.c \ elf_getarsym.c \ elf_getbase.c \ elf_getident.c \ elf_hash.c \ elf_kind.c \ elf_memory.c \ elf_next.c \ elf_rand.c \ elf_rawfile.c \ elf_phnum.c \ elf_shnum.c \ elf_shstrndx.c \ elf_scn.c \ elf_strptr.c \ elf_update.c \ elf_version.c \ gelf_cap.c \ gelf_checksum.c \ gelf_dyn.c \ gelf_ehdr.c \ gelf_getclass.c \ gelf_fsize.c \ gelf_move.c \ gelf_phdr.c \ gelf_rel.c \ gelf_rela.c \ gelf_shdr.c \ gelf_sym.c \ gelf_syminfo.c \ gelf_symshndx.c \ gelf_xlate.c \ libelf.c \ libelf_align.c \ libelf_allocate.c \ libelf_ar.c \ libelf_ar_util.c \ libelf_checksum.c \ libelf_data.c \ libelf_ehdr.c \ libelf_extended.c \ libelf_phdr.c \ libelf_shdr.c \ libelf_xlate.c \ ${GENSRCS} INCS= libelf.h gelf.h # # We need to link against the correct version of these files. One # solution is to include ../../sys in the include path. This causes # problems when a header file in sys depends on a file in another # part of the tree, e.g. a machine dependent header. # SRCS+= sys/elf32.h sys/elf64.h sys/elf_common.h GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES= ${GENSRCS} CLEANDIRS= sys CFLAGS+= -I${.CURDIR} -I. sys/elf32.h sys/elf64.h sys/elf_common.h: ${.CURDIR}/../../sys/${.TARGET} mkdir -p ${.OBJDIR}/sys ln -sf ${.CURDIR}/../../sys/${.TARGET} ${.TARGET} SHLIB_MAJOR= 1 MAN= elf.3 \ elf_begin.3 \ elf_cntl.3 \ elf_end.3 \ elf_errmsg.3 \ elf_fill.3 \ elf_flagdata.3 \ elf_getarhdr.3 \ elf_getarsym.3 \ elf_getbase.3 \ elf_getdata.3 \ elf_getident.3 \ elf_getscn.3 \ elf_getphdrnum.3 \ elf_getphnum.3 \ elf_getshdrnum.3 \ elf_getshnum.3 \ elf_getshdrstrndx.3 \ elf_getshstrndx.3 \ elf_hash.3 \ elf_kind.3 \ elf_memory.3 \ elf_next.3 \ elf_rawfile.3 \ elf_rand.3 \ elf_strptr.3 \ elf_update.3 \ elf_version.3 \ gelf.3 \ gelf_checksum.3 \ gelf_fsize.3 \ gelf_getcap.3 \ gelf_getclass.3 \ gelf_getdyn.3 \ gelf_getehdr.3 \ gelf_getmove.3 \ gelf_getphdr.3 \ gelf_getrel.3 \ gelf_getrela.3 \ gelf_getshdr.3 \ gelf_getsym.3 \ gelf_getsyminfo.3 \ gelf_getsymshndx.3 \ gelf_newehdr.3 \ gelf_newphdr.3 \ gelf_update_ehdr.3 \ gelf_xlatetof.3 MLINKS+= \ elf_errmsg.3 elf_errno.3 \ elf_flagdata.3 elf_flagehdr.3 \ elf_flagdata.3 elf_flagelf.3 \ elf_flagdata.3 elf_flagphdr.3 \ elf_flagdata.3 elf_flagscn.3 \ elf_flagdata.3 elf_flagshdr.3 \ elf_getdata.3 elf_newdata.3 \ elf_getdata.3 elf_rawdata.3 \ elf_getscn.3 elf_ndxscn.3 \ elf_getscn.3 elf_newscn.3 \ elf_getscn.3 elf_nextscn.3 \ elf_getshstrndx.3 elf_setshstrndx.3 \ gelf_getcap.3 gelf_update_cap.3 \ gelf_getdyn.3 gelf_update_dyn.3 \ gelf_getmove.3 gelf_update_move.3 \ gelf_getrel.3 gelf_update_rel.3 \ gelf_getrela.3 gelf_update_rela.3 \ gelf_getsym.3 gelf_update_sym.3 \ gelf_getsyminfo.3 gelf_update_syminfo.3 \ gelf_getsymshndx.3 gelf_update_symshndx.3 \ gelf_update_ehdr.3 gelf_update_phdr.3 \ gelf_update_ehdr.3 gelf_update_shdr.3 \ gelf_xlatetof.3 gelf_xlatetom.3 .for E in 32 64 MLINKS+= \ gelf_checksum.3 elf${E}_checksum.3 \ gelf_fsize.3 elf${E}_fsize.3 \ gelf_getehdr.3 elf${E}_getehdr.3 \ gelf_getphdr.3 elf${E}_getphdr.3 \ gelf_getshdr.3 elf${E}_getshdr.3 \ gelf_newehdr.3 elf${E}_newehdr.3 \ gelf_newphdr.3 elf${E}_newphdr.3 \ gelf_xlatetof.3 elf${E}_xlatetof.3 \ gelf_xlatetof.3 elf${E}_xlatetom.3 .endfor VERSION_MAP= ${.CURDIR}/Version.map LIBELF_TEST_HOOKS?= 1 .if defined(LIBELF_TEST_HOOKS) && (${LIBELF_TEST_HOOKS} > 0) CFLAGS+= -DLIBELF_TEST_HOOKS .endif libelf_convert.c: elf_types.m4 libelf_convert.m4 libelf_fsize.c: elf_types.m4 libelf_fsize.m4 libelf_msize.c: elf_types.m4 libelf_msize.m4 .include # Keep the .SUFFIXES line after the include of bsd.lib.mk .SUFFIXES: .m4 .c .m4.c: m4 -D SRCDIR=${.CURDIR} ${.IMPSRC} > ${.TARGET} freebsd-libs-10.1~svn273304/lib/libelf/gelf_getrel.30000644000000000000000000000656611361411226016652 0ustar .\" Copyright (c) 2006 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" This software is provided by Joseph Koshy ``as is'' and .\" any express or implied warranties, including, but not limited to, the .\" implied warranties of merchantability and fitness for a particular purpose .\" are disclaimed. in no event shall Joseph Koshy be liable .\" for any direct, indirect, incidental, special, exemplary, or consequential .\" damages (including, but not limited to, procurement of substitute goods .\" or services; loss of use, data, or profits; or business interruption) .\" however caused and on any theory of liability, whether in contract, strict .\" liability, or tort (including negligence or otherwise) arising in any way .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" .\" $FreeBSD$ .\" .Dd August 29, 2006 .Dt GELF_GETREL 3 .Os .Sh NAME .Nm gelf_getrel , .Nm gelf_update_rel .Nd read and update ELF relocation entries .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In gelf.h .Ft "GElf_Rel *" .Fn gelf_getrel "Elf_Data *data" "int ndx" "GElf_Rel *rel" .Ft int .Fn gelf_update_rel "Elf_Data *data" "int ndx" "GElf_Rel *rel" .Sh DESCRIPTION These convenience functions are used to retrieve and update class-dependent .Vt Elf32_Rel or .Vt Elf64_Rel structures in an ELF object. .Pp Argument .Ar data is an .Vt Elf_Data descriptor associated with a section of type .Dv SHT_REL . Argument .Ar ndx is the index of the entry being retrieved or updated. The class-independent .Vt GElf_Rel structure is described in .Xr gelf 3 . .Pp Function .Fn gelf_getrel retrieves the class-dependent entry at index .Ar ndx in data buffer .Ar data and copies it to the destination pointed to by argument .Ar rel after translation to class-independent form. .Pp Function .Fn gelf_update_rel converts the class-independent entry pointed to by argument .Ar rel to class-dependent form, and writes it to the entry at index .Ar ndx in the data buffer described by argument .Ar data . Function .Fn gelf_update_rel signals an error if any of the values in the class-independent representation exceeds the representable limits of the target type. .Sh RETURN VALUES Function .Fn gelf_getrel returns the value of argument .Ar rel if successful, or NULL in case of an error. Function .Fn gelf_update_rel returns a non-zero value if successful, or zero in case of an error. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT Arguments .Ar data or .Ar rel were NULL. .It Bq Er ELF_E_ARGUMENT Argument .Ar ndx was less than zero or larger than the number of entries in the data descriptor. .It Bq Er ELF_E_ARGUMENT Data descriptor .Ar data was not associated with a section of type .Dv SHT_REL . .It Bq Er ELF_E_RANGE A value was not representable in the target type. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 freebsd-libs-10.1~svn273304/lib/libelf/libelf_align.c0000644000000000000000000001052011421542132017041 0ustar /*- * Copyright (c) 2006 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "_libelf.h" struct align { int a32; int a64; }; #ifdef __GNUC__ #define MALIGN(N) { \ .a32 = __alignof__(Elf32_##N), \ .a64 = __alignof__(Elf64_##N) \ } #define MALIGN64(V) { \ .a32 = 0, \ .a64 = __alignof__(Elf64_##V) \ } #define MALIGN_WORD() { \ .a32 = __alignof__(int32_t), \ .a64 = __alignof__(int64_t) \ } #else #error Need the __alignof__ builtin. #endif #define UNSUPPORTED() { \ .a32 = 0, \ .a64 = 0 \ } static struct align malign[ELF_T_NUM] = { [ELF_T_ADDR] = MALIGN(Addr), [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, #if __FreeBSD_version >= 700025 [ELF_T_CAP] = MALIGN(Cap), #endif [ELF_T_DYN] = MALIGN(Dyn), [ELF_T_EHDR] = MALIGN(Ehdr), [ELF_T_HALF] = MALIGN(Half), #if __FreeBSD_version >= 700025 [ELF_T_LWORD] = MALIGN(Lword), [ELF_T_MOVE] = MALIGN(Move), #endif [ELF_T_MOVEP] = UNSUPPORTED(), #if __FreeBSD_version >= 700025 [ELF_T_NOTE] = MALIGN(Nhdr), #endif [ELF_T_OFF] = MALIGN(Off), [ELF_T_PHDR] = MALIGN(Phdr), [ELF_T_REL] = MALIGN(Rel), [ELF_T_RELA] = MALIGN(Rela), [ELF_T_SHDR] = MALIGN(Shdr), [ELF_T_SWORD] = MALIGN(Sword), [ELF_T_SXWORD] = MALIGN64(Sxword), [ELF_T_SYM] = MALIGN(Sym), #if __FreeBSD_version >= 700025 [ELF_T_SYMINFO] = MALIGN(Syminfo), #endif #if __FreeBSD_version >= 700009 [ELF_T_VDEF] = MALIGN(Verdef), [ELF_T_VNEED] = MALIGN(Verneed), #endif [ELF_T_WORD] = MALIGN(Word), [ELF_T_XWORD] = MALIGN64(Xword), #if __FreeBSD_version >= 800062 [ELF_T_GNUHASH] = MALIGN_WORD() #endif }; int _libelf_malign(Elf_Type t, int elfclass) { if (t >= ELF_T_NUM || (int) t < 0) return (0); return (elfclass == ELFCLASS32 ? malign[t].a32 : malign[t].a64); } #define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } static struct align falign[ELF_T_NUM] = { [ELF_T_ADDR] = FALIGN(4,8), [ELF_T_BYTE] = FALIGN(1,1), #if __FreeBSD_version >= 700025 [ELF_T_CAP] = FALIGN(4,8), #endif [ELF_T_DYN] = FALIGN(4,8), [ELF_T_EHDR] = FALIGN(4,8), [ELF_T_HALF] = FALIGN(2,2), #if __FreeBSD_version >= 700025 [ELF_T_LWORD] = FALIGN(8,8), [ELF_T_MOVE] = FALIGN(8,8), #endif [ELF_T_MOVEP] = UNSUPPORTED(), #if __FreeBSD_version >= 700025 [ELF_T_NOTE] = FALIGN(1,1), #endif [ELF_T_OFF] = FALIGN(4,8), [ELF_T_PHDR] = FALIGN(4,8), [ELF_T_REL] = FALIGN(4,8), [ELF_T_RELA] = FALIGN(4,8), [ELF_T_SHDR] = FALIGN(4,8), [ELF_T_SWORD] = FALIGN(4,4), [ELF_T_SXWORD] = FALIGN(0,8), [ELF_T_SYM] = FALIGN(4,8), #if __FreeBSD_version >= 700025 [ELF_T_SYMINFO] = FALIGN(2,2), #endif #if __FreeBSD_version >= 700009 [ELF_T_VDEF] = FALIGN(4,4), [ELF_T_VNEED] = FALIGN(4,4), #endif [ELF_T_WORD] = FALIGN(4,4), [ELF_T_XWORD] = FALIGN(0,8), #if __FreeBSD_version >= 800062 [ELF_T_GNUHASH] = FALIGN(4,8) #endif }; int _libelf_falign(Elf_Type t, int elfclass) { if (t >= ELF_T_NUM || (int) t < 0) return (0); return (elfclass == ELFCLASS32 ? falign[t].a32 : falign[t].a64); } freebsd-libs-10.1~svn273304/lib/libelf/libelf_phdr.c0000644000000000000000000000777011421545376016736 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "_libelf.h" void * _libelf_getphdr(Elf *e, int ec) { size_t phnum, phentsize; size_t fsz, msz; uint64_t phoff; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; void *ehdr, *phdr; int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((phdr = (ec == ELFCLASS32 ? (void *) e->e_u.e_elf.e_phdr.e_phdr32 : (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL) return (phdr); /* * Check the PHDR related fields in the EHDR for sanity. */ if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (NULL); phnum = e->e_u.e_elf.e_nphdr; if (ec == ELFCLASS32) { eh32 = (Elf32_Ehdr *) ehdr; phentsize = eh32->e_phentsize; phoff = (uint64_t) eh32->e_phoff; } else { eh64 = (Elf64_Ehdr *) ehdr; phentsize = eh64->e_phentsize; phoff = (uint64_t) eh64->e_phoff; } fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); assert(fsz > 0); if ((uint64_t) e->e_rawsize < (phoff + fsz)) { LIBELF_SET_ERROR(HEADER, 0); return (NULL); } msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT); assert(msz > 0); if ((phdr = calloc(phnum, msz)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } if (ec == ELFCLASS32) e->e_u.e_elf.e_phdr.e_phdr32 = phdr; else e->e_u.e_elf.e_phdr.e_phdr64 = phdr; xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec); (*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum, e->e_byteorder != LIBELF_PRIVATE(byteorder)); return (phdr); } void * _libelf_newphdr(Elf *e, int ec, size_t count) { void *ehdr, *newphdr, *oldphdr; size_t msz; if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) { LIBELF_SET_ERROR(SEQUENCE, 0); return (NULL); } assert(e->e_class == ec); assert(ec == ELFCLASS32 || ec == ELFCLASS64); assert(e->e_version == EV_CURRENT); msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version); assert(msz > 0); newphdr = NULL; if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } if (ec == ELFCLASS32) { if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) free(oldphdr); e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; } else { if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) free(oldphdr); e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; } e->e_u.e_elf.e_nphdr = count; elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); return (newphdr); } freebsd-libs-10.1~svn273304/lib/libkiconv/0000755000000000000000000000000012421417251015017 5ustar freebsd-libs-10.1~svn273304/lib/libkiconv/quirks.h0000644000000000000000000000340507735120361016515 0ustar /*- * Copyright (c) 2003 Ryuichiro Imura * 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. * * $FreeBSD$ */ #ifndef _KICONV_QUIRKS_H_ #define _KICONV_QUIRKS_H_ struct quirk_replace_list { uint16_t standard_code, vendor_code; }; const char *search_quirk(const char *, const char *, struct quirk_replace_list **, size_t *); uint16_t quirk_vendor2unix(uint16_t, struct quirk_replace_list *, size_t); uint16_t quirk_unix2vendor(uint16_t, struct quirk_replace_list *, size_t); #endif /* _KICONV_QUIRKS_H_ */ freebsd-libs-10.1~svn273304/lib/libkiconv/kiconv.30000644000000000000000000000640312113210372016370 0ustar .\" .\" Copyright (c) 2003 Ryuichiro Imura .\" 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. .\" .\" $FreeBSD$ .\" .Dd July 17, 2003 .Dt KICONV 3 .Os .Sh NAME .Nm kiconv_add_xlat16_cspair , .Nm kiconv_add_xlat16_cspairs , .Nm kiconv_add_xlat16_table .Nd kernel side iconv library .Sh LIBRARY .Lb libkiconv .Sh SYNOPSIS .In sys/iconv.h .Ft int .Fo kiconv_add_xlat16_cspair .Fa "const char *tocode" .Fa "const char *fromcode" .Fa "int flag" .Fc .Ft int .Fo kiconv_add_xlat16_cspairs .Fa "const char *foreigncode" .Fa "const char *localcode" .Fc .Ft int .Fo kiconv_add_xlat16_table .Fa "const char *tocode" .Fa "const char *fromcode" .Fa "const void *data" .Fa "int datalen" .Fc .Sh DESCRIPTION The .Nm kiconv library provides multi-byte character conversion tables for kernel side iconv service. .Pp The .Fn kiconv_add_xlat16_cspair function defines a conversion table using .Xr iconv 3 between .Fa fromcode charset and .Fa tocode charset. You can specify .Fa flag to determine if .Xr tolower 3 / .Xr toupper 3 conversion is included in the table. The .Fa flag has following values. .Pp .Bl -tag -width ".Dv KICONV_FROM_LOWER" -compact .It Dv KICONV_LOWER .It Dv KICONV_FROM_LOWER It generates a tolower table in addition to a character conversion table. The difference between two is tolower .Fa tocode or tolower .Fa fromcode . .It Dv KICONV_UPPER .It Dv KICONV_FROM_UPPER It generates a toupper table in addition to a character conversion table. The difference between two is toupper .Fa tocode or toupper .Fa fromcode . .El .Pp A tolower/toupper conversion is limited to single-byte characters. .Pp The .Fn kiconv_add_xlat16_cspairs function defines two conversion tables which are from .Fa localcode to .Fa foreigncode and from .Fa foreigncode to .Fa localcode . These conversion tables also contain both tolower and toupper tables. .Pp The .Fn kiconv_add_xlat16_table function defines a conversion table directly pointed by .Fa data whose length is .Fa datalen , not using .Xr iconv 3 . .Sh SEE ALSO .Xr iconv 3 , .Xr tolower 3 , .Xr toupper 3 freebsd-libs-10.1~svn273304/lib/libkiconv/Makefile0000644000000000000000000000064311765722631016475 0ustar # $FreeBSD$ SHLIBDIR?= /lib .include LIB= kiconv SRCS= kiconv_sysctl.c xlat16_iconv.c xlat16_sysctl.c SRCS+= quirks.c SHLIB_MAJOR= 4 MAN= kiconv.3 MLINKS+= kiconv.3 kiconv_add_xlat16_cspair.3 \ kiconv.3 kiconv_add_xlat16_cspairs.3 \ kiconv.3 kiconv_add_xlat16_table.3 CFLAGS+= -I${.CURDIR}/../../sys WARNS?= 1 .if ${MK_ICONV} == "no" CFLAGS+= -DICONV_DLOPEN .endif .include freebsd-libs-10.1~svn273304/lib/libkiconv/xlat16_sysctl.c0000644000000000000000000000541311217734244017714 0ustar /* * Copyright (c) 2000-2001, Boris Popov * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Boris Popov. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * 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. * * $FreeBSD$ */ /* * kiconv(3) requires shared linked, and reduce module size * when statically linked. */ #ifdef PIC #include #include #include #include #include #include int kiconv_add_xlat16_table(const char *to, const char *from, const void *data, int datalen) { struct iconv_add_in din; struct iconv_add_out dout; size_t olen; if (strlen(from) >= ICONV_CSNMAXLEN || strlen(to) >= ICONV_CSNMAXLEN) return (EINVAL); din.ia_version = ICONV_ADD_VER; strcpy(din.ia_converter, "xlat16"); strcpy(din.ia_from, from); strcpy(din.ia_to, to); din.ia_data = data; din.ia_datalen = datalen; olen = sizeof(dout); if (sysctlbyname("kern.iconv.add", &dout, &olen, &din, sizeof(din)) == -1) return (errno); return (0); } #else /* statically linked */ #include #include #include int kiconv_add_xlat16_table(const char *to __unused, const char *from __unused, const void *data __unused, int datalen __unused) { return (EINVAL); } #endif /* PIC */ freebsd-libs-10.1~svn273304/lib/libkiconv/kiconv_sysctl.c0000644000000000000000000000516111217776203020067 0ustar /*- * Copyright (c) 2005 Ryuichiro Imura * 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. * * $FreeBSD$ */ #include #include #include #include #include #include #include int kiconv_lookupconv(const char *drvname) { size_t size; if (sysctlbyname("kern.iconv.drvlist", NULL, &size, NULL, 0) == -1) return (errno); if (size > 0) { char *drivers, *drvp; drivers = malloc(size); if (drivers == NULL) return (ENOMEM); if (sysctlbyname("kern.iconv.drvlist", drivers, &size, NULL, 0) == -1) { free(drivers); return (errno); } for (drvp = drivers; *drvp != '\0'; drvp += strlen(drvp) + 1) if (strcmp(drvp, drvname) == 0) { free(drivers); return (0); } } return (ENOENT); } int kiconv_lookupcs(const char *tocode, const char *fromcode) { size_t i, size; struct iconv_cspair_info *csi, *csip; if (sysctlbyname("kern.iconv.cslist", NULL, &size, NULL, 0) == -1) return (errno); if (size > 0) { csi = malloc(size); if (csi == NULL) return (ENOMEM); if (sysctlbyname("kern.iconv.cslist", csi, &size, NULL, 0) == -1) { free(csi); return (errno); } for (i = 0, csip = csi; i < (size/sizeof(*csi)); i++, csip++){ if (strcmp(csip->cs_to, tocode) == 0 && strcmp(csip->cs_from, fromcode) == 0) { free(csi); return (0); } } } return (ENOENT); } freebsd-libs-10.1~svn273304/lib/libkiconv/xlat16_iconv.c0000644000000000000000000002421312202356365017507 0ustar /*- * Copyright (c) 2003, 2005 Ryuichiro Imura * 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. * * $FreeBSD$ */ /* * kiconv(3) requires shared linked, and reduce module size * when statically linked. */ #ifdef PIC #include #include #include #include #include #include #include #include #include #include #include #include #include "quirks.h" struct xlat16_table { uint32_t * idx[0x200]; void * data; size_t size; }; static struct xlat16_table kiconv_xlat16_open(const char *, const char *, int); static int chklocale(int, const char *); #ifdef ICONV_DLOPEN typedef void *iconv_t; static int my_iconv_init(void); static iconv_t (*my_iconv_open)(const char *, const char *); static size_t (*my_iconv)(iconv_t, const char **, size_t *, char **, size_t *); static int (*my_iconv_close)(iconv_t); #else #include #define my_iconv_init() 0 #define my_iconv_open iconv_open #define my_iconv iconv #define my_iconv_close iconv_close #endif static size_t my_iconv_char(iconv_t, const u_char **, size_t *, u_char **, size_t *); int kiconv_add_xlat16_cspair(const char *tocode, const char *fromcode, int flag) { int error; size_t idxsize; struct xlat16_table xt; void *data; char *p; const char unicode[] = ENCODING_UNICODE; if ((flag & KICONV_WCTYPE) == 0 && strcmp(unicode, tocode) != 0 && strcmp(unicode, fromcode) != 0 && kiconv_lookupconv(unicode) == 0) { error = kiconv_add_xlat16_cspair(unicode, fromcode, flag); if (error) return (-1); error = kiconv_add_xlat16_cspair(tocode, unicode, flag); return (error); } if (kiconv_lookupcs(tocode, fromcode) == 0) return (0); if (flag & KICONV_WCTYPE) xt = kiconv_xlat16_open(fromcode, fromcode, flag); else xt = kiconv_xlat16_open(tocode, fromcode, flag); if (xt.size == 0) return (-1); idxsize = sizeof(xt.idx); if ((idxsize + xt.size) > ICONV_CSMAXDATALEN) { errno = E2BIG; return (-1); } if ((data = malloc(idxsize + xt.size)) != NULL) { p = data; memcpy(p, xt.idx, idxsize); p += idxsize; memcpy(p, xt.data, xt.size); error = kiconv_add_xlat16_table(tocode, fromcode, data, (int)(idxsize + xt.size)); return (error); } return (-1); } int kiconv_add_xlat16_cspairs(const char *foreigncode, const char *localcode) { int error, locale; error = kiconv_add_xlat16_cspair(foreigncode, localcode, KICONV_FROM_LOWER | KICONV_FROM_UPPER); if (error) return (error); error = kiconv_add_xlat16_cspair(localcode, foreigncode, KICONV_LOWER | KICONV_UPPER); if (error) return (error); locale = chklocale(LC_CTYPE, localcode); if (locale == 0) { error = kiconv_add_xlat16_cspair(KICONV_WCTYPE_NAME, localcode, KICONV_WCTYPE); if (error) return (error); } return (0); } static struct xlat16_table kiconv_xlat16_open(const char *tocode, const char *fromcode, int lcase) { u_char src[3], dst[4], *srcp, *dstp, ud, ld; int us, ls, ret; uint16_t c; uint32_t table[0x80]; size_t inbytesleft, outbytesleft, pre_q_size, post_q_size; struct xlat16_table xt; struct quirk_replace_list *pre_q_list, *post_q_list; iconv_t cd; char *p; xt.data = NULL; xt.size = 0; src[2] = '\0'; dst[3] = '\0'; ret = my_iconv_init(); if (ret) return (xt); cd = my_iconv_open(search_quirk(tocode, fromcode, &pre_q_list, &pre_q_size), search_quirk(fromcode, tocode, &post_q_list, &post_q_size)); if (cd == (iconv_t) (-1)) return (xt); if ((xt.data = malloc(0x200 * 0x80 * sizeof(uint32_t))) == NULL) return (xt); p = xt.data; for (ls = 0 ; ls < 0x200 ; ls++) { xt.idx[ls] = NULL; for (us = 0 ; us < 0x80 ; us++) { srcp = src; dstp = dst; inbytesleft = 2; outbytesleft = 3; bzero(dst, outbytesleft); c = ((ls & 0x100 ? us | 0x80 : us) << 8) | (u_char)ls; if (lcase & KICONV_WCTYPE) { if ((c & 0xff) == 0) c >>= 8; if (iswupper(c)) { c = towlower(c); if ((c & 0xff00) == 0) c <<= 8; table[us] = c | XLAT16_HAS_LOWER_CASE; } else if (iswlower(c)) { c = towupper(c); if ((c & 0xff00) == 0) c <<= 8; table[us] = c | XLAT16_HAS_UPPER_CASE; } else table[us] = 0; /* * store not NULL */ if (table[us]) xt.idx[ls] = table; continue; } c = quirk_vendor2unix(c, pre_q_list, pre_q_size); src[0] = (u_char)(c >> 8); src[1] = (u_char)c; ret = my_iconv_char(cd, (const u_char **)&srcp, &inbytesleft, &dstp, &outbytesleft); if (ret == -1) { table[us] = 0; continue; } ud = (u_char)dst[0]; ld = (u_char)dst[1]; switch(outbytesleft) { case 0: #ifdef XLAT16_ACCEPT_3BYTE_CHR table[us] = (ud << 8) | ld; table[us] |= (u_char)dst[2] << 16; table[us] |= XLAT16_IS_3BYTE_CHR; #else table[us] = 0; continue; #endif break; case 1: table[us] = quirk_unix2vendor((ud << 8) | ld, post_q_list, post_q_size); if ((table[us] >> 8) == 0) table[us] |= XLAT16_ACCEPT_NULL_OUT; break; case 2: table[us] = ud; if (lcase & KICONV_LOWER && ud != tolower(ud)) { table[us] |= (u_char)tolower(ud) << 16; table[us] |= XLAT16_HAS_LOWER_CASE; } if (lcase & KICONV_UPPER && ud != toupper(ud)) { table[us] |= (u_char)toupper(ud) << 16; table[us] |= XLAT16_HAS_UPPER_CASE; } break; } switch(inbytesleft) { case 0: if ((ls & 0xff) == 0) table[us] |= XLAT16_ACCEPT_NULL_IN; break; case 1: c = ls > 0xff ? us | 0x80 : us; if (lcase & KICONV_FROM_LOWER && c != tolower(c)) { table[us] |= (u_char)tolower(c) << 16; table[us] |= XLAT16_HAS_FROM_LOWER_CASE; } if (lcase & KICONV_FROM_UPPER && c != toupper(c)) { table[us] |= (u_char)toupper(c) << 16; table[us] |= XLAT16_HAS_FROM_UPPER_CASE; } break; } if (table[us] == 0) continue; /* * store not NULL */ xt.idx[ls] = table; } if (xt.idx[ls]) { memcpy(p, table, sizeof(table)); p += sizeof(table); } } my_iconv_close(cd); xt.size = p - (char *)xt.data; xt.data = realloc(xt.data, xt.size); return (xt); } static int chklocale(int category, const char *code) { char *p; int error = -1; p = strchr(setlocale(category, NULL), '.'); if (p++) { error = strcasecmp(code, p); if (error) { /* XXX - can't avoid calling quirk here... */ error = strcasecmp(code, kiconv_quirkcs(p, KICONV_VENDOR_MICSFT)); } } return (error); } #ifdef ICONV_DLOPEN static int my_iconv_init(void) { void *iconv_lib; iconv_lib = dlopen("libiconv.so", RTLD_LAZY | RTLD_GLOBAL); if (iconv_lib == NULL) { warn("Unable to load iconv library: %s\n", dlerror()); errno = ENOENT; return (-1); } my_iconv_open = dlsym(iconv_lib, "iconv_open"); my_iconv = dlsym(iconv_lib, "iconv"); my_iconv_close = dlsym(iconv_lib, "iconv_close"); return (0); } #endif static size_t my_iconv_char(iconv_t cd, const u_char **ibuf, size_t * ilen, u_char **obuf, size_t * olen) { const u_char *sp; u_char *dp, ilocal[3], olocal[3]; u_char c1, c2; int ret; size_t ir, or; sp = *ibuf; dp = *obuf; ir = *ilen; bzero(*obuf, *olen); ret = my_iconv(cd, (const char **)&sp, ilen, (char **)&dp, olen); c1 = (*obuf)[0]; c2 = (*obuf)[1]; if (ret == -1) { if (*ilen == ir - 1 && (*ibuf)[1] == '\0' && (c1 || c2)) return (0); else return (-1); } /* * We must judge if inbuf is a single byte char or double byte char. * Here, to judge, try first byte(*sp) conversion and compare. */ ir = 1; or = 3; bzero(olocal, or); memcpy(ilocal, *ibuf, sizeof(ilocal)); sp = ilocal; dp = olocal; if ((my_iconv(cd,(const char **)&sp, &ir, (char **)&dp, &or)) != -1) { if (olocal[0] != c1) return (ret); if (olocal[1] == c2 && (*ibuf)[1] == '\0') { /* * inbuf is a single byte char */ *ilen = 1; *olen = or; return (ret); } switch(or) { case 0: case 1: if (olocal[1] == c2) { /* * inbuf is a single byte char, * so return false here. */ return (-1); } else { /* * inbuf is a double byte char */ return (ret); } break; case 2: /* * should compare second byte of inbuf */ break; } } else { /* * inbuf clould not be splitted, so inbuf is * a double byte char. */ return (ret); } /* * try second byte(*(sp+1)) conversion, and compare */ ir = 1; or = 3; bzero(olocal, or); sp = ilocal + 1; dp = olocal; if ((my_iconv(cd,(const char **)&sp, &ir, (char **)&dp, &or)) != -1) { if (olocal[0] == c2) /* * inbuf is a single byte char */ return (-1); } return (ret); } #else /* statically linked */ #include #include #include int kiconv_add_xlat16_cspair(const char *tocode __unused, const char *fromcode __unused, int flag __unused) { errno = EINVAL; return (-1); } int kiconv_add_xlat16_cspairs(const char *tocode __unused, const char *fromcode __unused) { errno = EINVAL; return (-1); } #endif /* PIC */ freebsd-libs-10.1~svn273304/lib/libkiconv/quirks.c0000644000000000000000000001277311217734244016521 0ustar /*- * Copyright (c) 2003 Ryuichiro Imura * 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. * * $FreeBSD$ */ /* * kiconv(3) requires shared linked, and reduce module size * when statically linked. */ #ifdef PIC /* * Why do we need quirks? * Since each vendors has their own Unicode mapping rules, * we need some quirks until iconv(3) supports them. * We can define Microsoft mappings here. * * For example, the eucJP and Unocode mapping rule is based on * the JIS standard. Since Microsoft uses cp932 for Unicode mapping * witch is not truly based on the JIS standard, reading a file * system created by Microsoft Windows family using eucJP/Unicode * mapping rule will cause a problem. That's why we define eucJP-ms here. * The eucJP-ms has been defined by The Open Group Japan Vendor Coucil. * * Well, Apple Mac OS also has their own Unicode mappings, * but we won't require these quirks here, because HFS doesn't have * Unicode and HFS+ has decomposed Unicode which can not be * handled by this xlat16 converter. */ #include #include #include #include #include "quirks.h" /* * All lists of quirk character set */ static struct { int vendor; /* reserved for non MS mapping */ const char *base_codeset, *quirk_codeset; } quirk_list[] = { { KICONV_VENDOR_MICSFT, "eucJP", "eucJP-ms" }, { KICONV_VENDOR_MICSFT, "EUC-JP", "eucJP-ms" }, { KICONV_VENDOR_MICSFT, "SJIS", "SJIS-ms" }, { KICONV_VENDOR_MICSFT, "Shift_JIS", "SJIS-ms" }, { KICONV_VENDOR_MICSFT, "Big5", "Big5-ms" } }; /* * The character list to replace for Japanese MS-Windows. */ static struct quirk_replace_list quirk_jis_cp932[] = { { 0x00a2, 0xffe0 }, /* Cent Sign, Fullwidth Cent Sign */ { 0x00a3, 0xffe1 }, /* Pound Sign, Fullwidth Pound Sign */ { 0x00ac, 0xffe2 }, /* Not Sign, Fullwidth Not Sign */ { 0x2016, 0x2225 }, /* Double Vertical Line, Parallel To */ { 0x203e, 0x007e }, /* Overline, Tilde */ { 0x2212, 0xff0d }, /* Minus Sign, Fullwidth Hyphenminus */ { 0x301c, 0xff5e } /* Wave Dash, Fullwidth Tilde */ }; /* * All entries of quirks */ #define NumOf(n) (sizeof((n)) / sizeof((n)[0])) static struct { const char *quirk_codeset, *iconv_codeset, *pair_codeset; struct quirk_replace_list (*replace_list)[]; size_t num_of_replaces; } quirk_table[] = { { "eucJP-ms", "eucJP", ENCODING_UNICODE, (struct quirk_replace_list (*)[])&quirk_jis_cp932, NumOf(quirk_jis_cp932) }, { "SJIS-ms", "CP932", ENCODING_UNICODE, /* XXX - quirk_replace_list should be NULL */ (struct quirk_replace_list (*)[])&quirk_jis_cp932, NumOf(quirk_jis_cp932) }, { "Big5-ms", "CP950", ENCODING_UNICODE, NULL, 0 } }; const char * kiconv_quirkcs(const char* base, int vendor) { size_t i; /* * We should compare codeset names ignoring case here, * so that quirk could be used for all of the user input * patterns. */ for (i = 0; i < NumOf(quirk_list); i++) if (quirk_list[i].vendor == vendor && strcasecmp(quirk_list[i].base_codeset, base) == 0) return (quirk_list[i].quirk_codeset); return (base); } /* * Internal Functions */ const char * search_quirk(const char *given_codeset, const char *pair_codeset, struct quirk_replace_list **replace_list, size_t *num_of_replaces) { size_t i; *replace_list = NULL; *num_of_replaces = 0; for (i = 0; i < NumOf(quirk_table); i++) if (strcmp(quirk_table[i].quirk_codeset, given_codeset) == 0) { if (strcmp(quirk_table[i].pair_codeset, pair_codeset) == 0) { *replace_list = *quirk_table[i].replace_list; *num_of_replaces = quirk_table[i].num_of_replaces; } return (quirk_table[i].iconv_codeset); } return (given_codeset); } uint16_t quirk_vendor2unix(uint16_t c, struct quirk_replace_list *replace_list, size_t num) { size_t i; for (i = 0; i < num; i++) if (replace_list[i].vendor_code == c) return (replace_list[i].standard_code); return (c); } uint16_t quirk_unix2vendor(uint16_t c, struct quirk_replace_list *replace_list, size_t num) { size_t i; for (i = 0; i < num; i++) if (replace_list[i].standard_code == c) return (replace_list[i].vendor_code); return (c); } #else /* statically linked */ #include #include const char * kiconv_quirkcs(const char* base __unused, int vendor __unused) { return (base); } #endif /* PIC */ freebsd-libs-10.1~svn273304/lib/libnetgraph/0000755000000000000000000000000012421417254015341 5ustar freebsd-libs-10.1~svn273304/lib/libnetgraph/internal.h0000644000000000000000000000562410622067701017334 0ustar /* * internal.h * * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, use and * redistribution of this software, in source or object code forms, with or * without modifications are expressly permitted by Whistle Communications; * provided, however, that: * 1. Any and all reproductions of the source or object code must include the * copyright notice above and the following disclaimer of warranties; and * 2. No rights are granted, in any manner or form, to use Whistle * Communications, Inc. trademarks, including the mark "WHISTLE * COMMUNICATIONS" on advertising, endorsements, or otherwise except as * such appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Archie Cobbs * * $FreeBSD$ * $Whistle: internal.h,v 1.5 1999/01/20 00:57:22 archie Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* the 'sockaddr overhead' for a netgraph address. This is everything before * the string that constitutes the address. */ #define NGSA_OVERHEAD (offsetof(struct sockaddr_ng, sg_data)) extern int _gNgDebugLevel; extern void (*_NgLog)(const char *fmt, ...); extern void (*_NgLogx)(const char *fmt, ...); #define NGLOG (*_NgLog) #define NGLOGX (*_NgLogx) extern void _NgDebugSockaddr(const struct sockaddr_ng *sg); extern void _NgDebugMsg(const struct ng_mesg *msg, const char *path); extern void _NgDebugBytes(const u_char *ptr, int size); freebsd-libs-10.1~svn273304/lib/libnetgraph/sock.c0000644000000000000000000002012112065103045016432 0ustar /* * sock.c * * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, use and * redistribution of this software, in source or object code forms, with or * without modifications are expressly permitted by Whistle Communications; * provided, however, that: * 1. Any and all reproductions of the source or object code must include the * copyright notice above and the following disclaimer of warranties; and * 2. No rights are granted, in any manner or form, to use Whistle * Communications, Inc. trademarks, including the mark "WHISTLE * COMMUNICATIONS" on advertising, endorsements, or otherwise except as * such appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Archie Cobbs * * $Whistle: sock.c,v 1.12 1999/01/20 00:57:23 archie Exp $ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "netgraph.h" #include "internal.h" /* The socket node type KLD */ #define NG_SOCKET_KLD "ng_socket.ko" /* * Create a socket type node and give it the supplied name. * Return data and control sockets corresponding to the node. * Returns -1 if error and sets errno. */ int NgMkSockNode(const char *name, int *csp, int *dsp) { char namebuf[NG_NODESIZ]; int cs = -1; /* control socket */ int ds = -1; /* data socket */ int errnosv; /* Empty name means no name */ if (name && *name == 0) name = NULL; /* Create control socket; this also creates the netgraph node. If we get an EAFNOSUPPORT then the socket node type is not loaded, so load it and try again. */ if ((cs = socket(AF_NETGRAPH, SOCK_DGRAM, NG_CONTROL)) < 0) { if (errno == EAFNOSUPPORT) { if (kldload(NG_SOCKET_KLD) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("can't load %s", NG_SOCKET_KLD); goto errout; } cs = socket(AF_NETGRAPH, SOCK_DGRAM, NG_CONTROL); if (cs >= 0) goto gotNode; } errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("socket"); goto errout; } gotNode: /* Assign the node the desired name, if any */ if (name != NULL) { u_char sbuf[NG_NODESIZ + NGSA_OVERHEAD]; struct sockaddr_ng *const sg = (struct sockaddr_ng *) sbuf; /* Assign name */ strlcpy(sg->sg_data, name, NG_NODESIZ); sg->sg_family = AF_NETGRAPH; sg->sg_len = strlen(sg->sg_data) + 1 + NGSA_OVERHEAD; if (bind(cs, (struct sockaddr *) sg, sg->sg_len) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("bind(%s)", sg->sg_data); goto errout; } /* Save node name */ strlcpy(namebuf, name, sizeof(namebuf)); } else if (dsp != NULL) { u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)]; struct ng_mesg *const resp = (struct ng_mesg *) rbuf; struct nodeinfo *const ni = (struct nodeinfo *) resp->data; /* Find out the node ID */ if (NgSendMsg(cs, ".", NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("send nodeinfo"); goto errout; } if (NgRecvMsg(cs, resp, sizeof(rbuf), NULL) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("recv nodeinfo"); goto errout; } /* Save node "name" */ snprintf(namebuf, sizeof(namebuf), "[%lx]", (u_long) ni->id); } /* Create data socket if desired */ if (dsp != NULL) { u_char sbuf[NG_NODESIZ + 1 + NGSA_OVERHEAD]; struct sockaddr_ng *const sg = (struct sockaddr_ng *) sbuf; /* Create data socket, initially just "floating" */ if ((ds = socket(AF_NETGRAPH, SOCK_DGRAM, NG_DATA)) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("socket"); goto errout; } /* Associate the data socket with the node */ snprintf(sg->sg_data, NG_NODESIZ + 1, "%s:", namebuf); sg->sg_family = AF_NETGRAPH; sg->sg_len = strlen(sg->sg_data) + 1 + NGSA_OVERHEAD; if (connect(ds, (struct sockaddr *) sg, sg->sg_len) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("connect(%s)", sg->sg_data); goto errout; } } /* Return the socket(s) */ if (csp) *csp = cs; else close(cs); if (dsp) *dsp = ds; return (0); errout: /* Failed */ if (cs >= 0) close(cs); if (ds >= 0) close(ds); errno = errnosv; return (-1); } /* * Assign a globally unique name to a node * Returns -1 if error and sets errno. */ int NgNameNode(int cs, const char *path, const char *fmt, ...) { struct ngm_name ngn; va_list args; /* Build message arg */ va_start(args, fmt); vsnprintf(ngn.name, sizeof(ngn.name), fmt, args); va_end(args); /* Send message */ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE, NGM_NAME, &ngn, sizeof(ngn)) < 0) { if (_gNgDebugLevel >= 1) NGLOGX("%s: failed", __func__); return (-1); } /* Done */ return (0); } /* * Read a packet from a data socket * Returns -1 if error and sets errno. */ int NgRecvData(int ds, u_char * buf, size_t len, char *hook) { u_char frombuf[NG_HOOKSIZ + NGSA_OVERHEAD]; struct sockaddr_ng *const from = (struct sockaddr_ng *) frombuf; socklen_t fromlen = sizeof(frombuf); int rtn, errnosv; /* Read packet */ rtn = recvfrom(ds, buf, len, 0, (struct sockaddr *) from, &fromlen); if (rtn < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("recvfrom"); errno = errnosv; return (-1); } /* Copy hook name */ if (hook != NULL) strlcpy(hook, from->sg_data, NG_HOOKSIZ); /* Debugging */ if (_gNgDebugLevel >= 2) { NGLOGX("READ %s from hook \"%s\" (%d bytes)", rtn ? "PACKET" : "EOF", from->sg_data, rtn); if (_gNgDebugLevel >= 3) _NgDebugBytes(buf, rtn); } /* Done */ return (rtn); } /* * Identical to NgRecvData() except buffer is dynamically allocated. */ int NgAllocRecvData(int ds, u_char **buf, char *hook) { int len; socklen_t optlen; optlen = sizeof(len); if (getsockopt(ds, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || (*buf = malloc(len)) == NULL) return (-1); if ((len = NgRecvData(ds, *buf, len, hook)) < 0) free(*buf); return (len); } /* * Write a packet to a data socket. The packet will be sent * out the corresponding node on the specified hook. * Returns -1 if error and sets errno. */ int NgSendData(int ds, const char *hook, const u_char * buf, size_t len) { u_char sgbuf[NG_HOOKSIZ + NGSA_OVERHEAD]; struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf; int errnosv; /* Set up destination hook */ sg->sg_family = AF_NETGRAPH; strlcpy(sg->sg_data, hook, NG_HOOKSIZ); sg->sg_len = strlen(sg->sg_data) + 1 + NGSA_OVERHEAD; /* Debugging */ if (_gNgDebugLevel >= 2) { NGLOGX("WRITE PACKET to hook \"%s\" (%d bytes)", hook, len); _NgDebugSockaddr(sg); if (_gNgDebugLevel >= 3) _NgDebugBytes(buf, len); } /* Send packet */ if (sendto(ds, buf, len, 0, (struct sockaddr *) sg, sg->sg_len) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("sendto(%s)", sg->sg_data); errno = errnosv; return (-1); } /* Done */ return (0); } freebsd-libs-10.1~svn273304/lib/libnetgraph/netgraph.h0000644000000000000000000000602610005544452017323 0ustar /* * netgraph.h * * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, use and * redistribution of this software, in source or object code forms, with or * without modifications are expressly permitted by Whistle Communications; * provided, however, that: * 1. Any and all reproductions of the source or object code must include the * copyright notice above and the following disclaimer of warranties; and * 2. No rights are granted, in any manner or form, to use Whistle * Communications, Inc. trademarks, including the mark "WHISTLE * COMMUNICATIONS" on advertising, endorsements, or otherwise except as * such appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Archie Cobbs * * $FreeBSD$ * $Whistle: netgraph.h,v 1.7 1999/01/20 00:57:23 archie Exp $ */ #ifndef _NETGRAPH_H_ #define _NETGRAPH_H_ #include #include __BEGIN_DECLS int NgMkSockNode(const char *, int *, int *); int NgNameNode(int, const char *, const char *, ...) __printflike(3, 4); int NgSendMsg(int, const char *, int, int, const void *, size_t); int NgSendAsciiMsg(int, const char *, const char *, ...) __printflike(3, 4); int NgSendReplyMsg(int, const char *, const struct ng_mesg *, const void *, size_t); int NgRecvMsg(int, struct ng_mesg *, size_t, char *); int NgAllocRecvMsg(int, struct ng_mesg **, char *); int NgRecvAsciiMsg(int, struct ng_mesg *, size_t, char *); int NgAllocRecvAsciiMsg(int, struct ng_mesg **, char *); int NgSendData(int, const char *, const u_char *, size_t); int NgRecvData(int, u_char *, size_t, char *); int NgAllocRecvData(int, u_char **, char *); int NgSetDebug(int); void NgSetErrLog(void (*)(const char *fmt, ...), void (*)(const char *fmt, ...)); __END_DECLS #endif freebsd-libs-10.1~svn273304/lib/libnetgraph/Makefile0000644000000000000000000000127011230653404016775 0ustar # $FreeBSD$ # $Whistle: Makefile,v 1.4 1999/01/17 03:41:02 julian Exp $ LIB= netgraph WARNS?= 3 MAN= netgraph.3 SHLIB_MAJOR= 4 SRCS= sock.c msg.c debug.c INCS= netgraph.h MLINKS+= netgraph.3 NgMkSockNode.3 MLINKS+= netgraph.3 NgNameNode.3 MLINKS+= netgraph.3 NgSendMsg.3 MLINKS+= netgraph.3 NgSendAsciiMsg.3 MLINKS+= netgraph.3 NgSendMsgReply.3 MLINKS+= netgraph.3 NgRecvMsg.3 MLINKS+= netgraph.3 NgAllocRecvMsg.3 MLINKS+= netgraph.3 NgRecvAsciiMsg.3 MLINKS+= netgraph.3 NgAllocRecvAsciiMsg.3 MLINKS+= netgraph.3 NgSendData.3 MLINKS+= netgraph.3 NgRecvData.3 MLINKS+= netgraph.3 NgAllocRecvData.3 MLINKS+= netgraph.3 NgSetDebug.3 MLINKS+= netgraph.3 NgSetErrLog.3 .include freebsd-libs-10.1~svn273304/lib/libnetgraph/msg.c0000644000000000000000000002351112117353207016274 0ustar /* * msg.c * * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, use and * redistribution of this software, in source or object code forms, with or * without modifications are expressly permitted by Whistle Communications; * provided, however, that: * 1. Any and all reproductions of the source or object code must include the * copyright notice above and the following disclaimer of warranties; and * 2. No rights are granted, in any manner or form, to use Whistle * Communications, Inc. trademarks, including the mark "WHISTLE * COMMUNICATIONS" on advertising, endorsements, or otherwise except as * such appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Archie Cobbs * * $Whistle: msg.c,v 1.9 1999/01/20 00:57:23 archie Exp $ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "netgraph.h" #include "internal.h" /* Next message token value */ static int gMsgId; /* For delivering both messages and replies */ static int NgDeliverMsg(int cs, const char *path, const struct ng_mesg *hdr, const void *args, size_t arglen); /* * Send a message to a node using control socket node "cs". * Returns -1 if error and sets errno appropriately. * If successful, returns the message ID (token) used. */ int NgSendMsg(int cs, const char *path, int cookie, int cmd, const void *args, size_t arglen) { struct ng_mesg msg; /* Prepare message header */ memset(&msg, 0, sizeof(msg)); msg.header.version = NG_VERSION; msg.header.typecookie = cookie; if (++gMsgId < 0) gMsgId = 1; msg.header.token = gMsgId; msg.header.flags = NGF_ORIG; msg.header.cmd = cmd; snprintf((char *)msg.header.cmdstr, NG_CMDSTRSIZ, "cmd%d", cmd); /* Deliver message */ if (NgDeliverMsg(cs, path, &msg, args, arglen) < 0) return (-1); return (msg.header.token); } /* * Send a message given in ASCII format. We first ask the node to translate * the command into binary, and then we send the binary. */ int NgSendAsciiMsg(int cs, const char *path, const char *fmt, ...) { struct ng_mesg *reply, *binary, *ascii; char *buf, *cmd, *args; va_list fmtargs; int token; /* Parse out command and arguments */ va_start(fmtargs, fmt); vasprintf(&buf, fmt, fmtargs); va_end(fmtargs); if (buf == NULL) return (-1); /* Parse out command, arguments */ for (cmd = buf; isspace(*cmd); cmd++) ; for (args = cmd; *args != '\0' && !isspace(*args); args++) ; if (*args != '\0') { while (isspace(*args)) *args++ = '\0'; } /* Get a bigger buffer to hold inner message header plus arg string */ if ((ascii = malloc(sizeof(struct ng_mesg) + strlen(args) + 1)) == NULL) { free(buf); return (-1); } memset(ascii, 0, sizeof(*ascii)); /* Build inner header (only need cmdstr, arglen, and data fields) */ strncpy((char *)ascii->header.cmdstr, cmd, sizeof(ascii->header.cmdstr) - 1); strcpy(ascii->data, args); ascii->header.arglen = strlen(ascii->data) + 1; free(buf); /* Send node a request to convert ASCII to binary */ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE, NGM_ASCII2BINARY, (u_char *)ascii, sizeof(*ascii) + ascii->header.arglen) < 0) { free(ascii); return (-1); } free(ascii); /* Get reply */ if (NgAllocRecvMsg(cs, &reply, NULL) < 0) return (-1); /* Now send binary version */ binary = (struct ng_mesg *)reply->data; if (++gMsgId < 0) gMsgId = 1; binary->header.token = gMsgId; binary->header.version = NG_VERSION; if (NgDeliverMsg(cs, path, binary, binary->data, binary->header.arglen) < 0) { free(reply); return (-1); } token = binary->header.token; free(reply); return (token); } /* * Send a message that is a reply to a previously received message. * Returns -1 and sets errno on error, otherwise returns zero. */ int NgSendReplyMsg(int cs, const char *path, const struct ng_mesg *msg, const void *args, size_t arglen) { struct ng_mesg rep; /* Prepare message header */ rep = *msg; rep.header.flags = NGF_RESP; /* Deliver message */ return (NgDeliverMsg(cs, path, &rep, args, arglen)); } /* * Send a message to a node using control socket node "cs". * Returns -1 if error and sets errno appropriately, otherwise zero. */ static int NgDeliverMsg(int cs, const char *path, const struct ng_mesg *hdr, const void *args, size_t arglen) { u_char sgbuf[NG_PATHSIZ + NGSA_OVERHEAD]; struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf; u_char *buf = NULL; struct ng_mesg *msg; int errnosv = 0; int rtn = 0; /* Sanity check */ if (args == NULL) arglen = 0; /* Get buffer */ if ((buf = malloc(sizeof(*msg) + arglen)) == NULL) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("malloc"); rtn = -1; goto done; } msg = (struct ng_mesg *) buf; /* Finalize message */ *msg = *hdr; msg->header.arglen = arglen; memcpy(msg->data, args, arglen); /* Prepare socket address */ sg->sg_family = AF_NETGRAPH; /* XXX handle overflow */ strlcpy(sg->sg_data, path, NG_PATHSIZ); sg->sg_len = strlen(sg->sg_data) + 1 + NGSA_OVERHEAD; /* Debugging */ if (_gNgDebugLevel >= 2) { NGLOGX("SENDING %s:", (msg->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE"); _NgDebugSockaddr(sg); _NgDebugMsg(msg, sg->sg_data); } /* Send it */ if (sendto(cs, msg, sizeof(*msg) + arglen, 0, (struct sockaddr *) sg, sg->sg_len) < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("sendto(%s)", sg->sg_data); rtn = -1; goto done; } /* Wait for reply if there should be one. */ if (msg->header.cmd & NGM_HASREPLY && !(msg->header.flags & NGF_RESP)) { struct pollfd rfds; int n; rfds.fd = cs; rfds.events = POLLIN; rfds.revents = 0; n = poll(&rfds, 1, INFTIM); if (n == -1) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("poll"); rtn = -1; } } done: /* Done */ free(buf); /* OK if buf is NULL */ errno = errnosv; return (rtn); } /* * Receive a control message. * * On error, this returns -1 and sets errno. * Otherwise, it returns the length of the received reply. */ int NgRecvMsg(int cs, struct ng_mesg *rep, size_t replen, char *path) { u_char sgbuf[NG_PATHSIZ + NGSA_OVERHEAD]; struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf; socklen_t sglen = sizeof(sgbuf); int len, errnosv; /* Read reply */ len = recvfrom(cs, rep, replen, 0, (struct sockaddr *) sg, &sglen); if (len < 0) { errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("recvfrom"); goto errout; } if (path != NULL) strlcpy(path, sg->sg_data, NG_PATHSIZ); /* Debugging */ if (_gNgDebugLevel >= 2) { NGLOGX("RECEIVED %s:", (rep->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE"); _NgDebugSockaddr(sg); _NgDebugMsg(rep, sg->sg_data); } /* Done */ return (len); errout: errno = errnosv; return (-1); } /* * Identical to NgRecvMsg() except buffer is dynamically allocated. */ int NgAllocRecvMsg(int cs, struct ng_mesg **rep, char *path) { int len; socklen_t optlen; optlen = sizeof(len); if (getsockopt(cs, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || (*rep = malloc(len)) == NULL) return (-1); if ((len = NgRecvMsg(cs, *rep, len, path)) < 0) free(*rep); return (len); } /* * Receive a control message and convert the arguments to ASCII */ int NgRecvAsciiMsg(int cs, struct ng_mesg *reply, size_t replen, char *path) { struct ng_mesg *msg, *ascii; int bufSize, errnosv; u_char *buf; /* Allocate buffer */ bufSize = 2 * sizeof(*reply) + replen; if ((buf = malloc(bufSize)) == NULL) return (-1); msg = (struct ng_mesg *)buf; ascii = (struct ng_mesg *)msg->data; /* Get binary message */ if (NgRecvMsg(cs, msg, bufSize, path) < 0) goto fail; memcpy(reply, msg, sizeof(*msg)); /* Ask originating node to convert the arguments to ASCII */ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE, NGM_BINARY2ASCII, msg, sizeof(*msg) + msg->header.arglen) < 0) goto fail; if (NgRecvMsg(cs, msg, bufSize, NULL) < 0) goto fail; /* Copy result to client buffer */ if (sizeof(*ascii) + ascii->header.arglen > replen) { errno = ERANGE; fail: errnosv = errno; free(buf); errno = errnosv; return (-1); } strncpy(reply->data, ascii->data, ascii->header.arglen); /* Done */ free(buf); return (0); } /* * Identical to NgRecvAsciiMsg() except buffer is dynamically allocated. */ int NgAllocRecvAsciiMsg(int cs, struct ng_mesg **reply, char *path) { int len; socklen_t optlen; optlen = sizeof(len); if (getsockopt(cs, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || (*reply = malloc(len)) == NULL) return (-1); if ((len = NgRecvAsciiMsg(cs, *reply, len, path)) < 0) free(*reply); return (len); } freebsd-libs-10.1~svn273304/lib/libnetgraph/netgraph.30000644000000000000000000002556512267717034017261 0ustar .\" Copyright (c) 1996-1999 Whistle Communications, Inc. .\" All rights reserved. .\" .\" Subject to the following obligations and disclaimer of warranty, use and .\" redistribution of this software, in source or object code forms, with or .\" without modifications are expressly permitted by Whistle Communications; .\" provided, however, that: .\" 1. Any and all reproductions of the source or object code must include the .\" copyright notice above and the following disclaimer of warranties; and .\" 2. No rights are granted, in any manner or form, to use Whistle .\" Communications, Inc. trademarks, including the mark "WHISTLE .\" COMMUNICATIONS" on advertising, endorsements, or otherwise except as .\" such appears in the above copyright notice or in the software. .\" .\" THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND .\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO .\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, .\" INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF .\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. .\" WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY .\" REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS .\" SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. .\" IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES .\" RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING .\" WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, .\" PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR .\" SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY .\" OF SUCH DAMAGE. .\" .\" Author: Archie Cobbs .\" .\" $FreeBSD$ .\" $Whistle: netgraph.3,v 1.7 1999/01/25 07:14:06 archie Exp $ .\" .Dd November 25, 2013 .Dt NETGRAPH 3 .Os .Sh NAME .Nm NgMkSockNode , .Nm NgNameNode , .Nm NgSendMsg , .Nm NgSendAsciiMsg , .Nm NgSendMsgReply , .Nm NgRecvMsg , .Nm NgAllocRecvMsg , .Nm NgRecvAsciiMsg , .Nm NgAllocRecvAsciiMsg , .Nm NgSendData , .Nm NgRecvData , .Nm NgAllocRecvData , .Nm NgSetDebug , .Nm NgSetErrLog .Nd netgraph user library .Sh LIBRARY .Lb libnetgraph .Sh SYNOPSIS .In netgraph/netgraph.h .Ft int .Fn NgMkSockNode "const char *name" "int *csp" "int *dsp" .Ft int .Fn NgNameNode "int cs" "const char *path" "const char *fmt" ... .Ft int .Fo NgSendMsg .Fa "int cs" "const char *path" "int cookie" "int cmd" "const void *arg" .Fa "size_t arglen" .Fc .Ft int .Fn NgSendAsciiMsg "int cs" "const char *path" "const char *fmt" ... .Ft int .Fo NgSendMsgReply .Fa "int cs" "const char *path" "struct ng_mesg *msg" "const void *arg" .Fa "size_t arglen" .Fc .Ft int .Fn NgRecvMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path" .Ft int .Fn NgAllocRecvMsg "int cs" "struct ng_mesg **rep" "char *path" .Ft int .Fn NgRecvAsciiMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path" .Ft int .Fn NgAllocRecvAsciiMsg "int cs" "struct ng_mesg **rep" "char *path" .Ft int .Fn NgSendData "int ds" "const char *hook" "const u_char *buf" "size_t len" .Ft int .Fn NgRecvData "int ds" "u_char *buf" "size_t len" "char *hook" .Ft int .Fn NgAllocRecvData "int ds" "u_char **buf" "char *hook" .Ft int .Fn NgSetDebug "int level" .Ft void .Fo NgSetErrLog .Fa "void \*[lp]*log\*[rp]\*[lp]const char *fmt, ...\*[rp]" .Fa "void \*[lp]*logx\*[rp]\*[lp]const char *fmt, ...\*[rp]" .Fc .Sh DESCRIPTION These functions facilitate user-mode program participation in the kernel .Xr netgraph 4 graph-based networking system, by utilizing the netgraph .Vt socket node type (see .Xr ng_socket 4 ) . .Pp The .Fn NgMkSockNode function should be called first, to create a new .Vt socket type netgraph node with associated control and data sockets. If .Fa name is .No non- Ns Dv NULL , the node will have that global name assigned to it. The .Fa csp and .Fa dsp arguments will be set to the newly opened control and data sockets associated with the node; either .Fa csp or .Fa dsp may be .Dv NULL if only one socket is desired. The .Fn NgMkSockNode function loads the .Vt socket node type KLD if it is not already loaded. .Pp The .Fn NgNameNode function assigns a global name to the node addressed by .Fa path . .Pp The .Fn NgSendMsg function sends a binary control message from the .Vt socket node associated with control socket .Fa cs to the node addressed by .Fa path . The .Fa cookie indicates how to interpret .Fa cmd , which indicates a specific command. Extra argument data (if any) is specified by .Fa arg and .Fa arglen . The .Fa cookie , cmd , and argument data are defined by the header file corresponding to the type of the node being addressed. The unique, non-negative token value chosen for use in the message header is returned. This value is typically used to associate replies. .Pp Use .Fn NgSendMsgReply to send reply to a previously received control message. The original message header should be pointed to by .Fa msg . .Pp The .Fn NgSendAsciiMsg function performs the same function as .Fn NgSendMsg , but adds support for .Tn ASCII encoding of control messages. The .Fn NgSendAsciiMsg function formats its input a la .Xr printf 3 and then sends the resulting .Tn ASCII string to the node in a .Dv NGM_ASCII2BINARY control message. The node returns a binary version of the message, which is then sent back to the node just as with .Fn NgSendMsg . As with .Fn NgSendMsg , the message token value is returned. Note that .Tn ASCII conversion may not be supported by all node types. .Pp The .Fn NgRecvMsg function reads the next control message received by the node associated with control socket .Fa cs . The message and any extra argument data must fit in .Fa replen bytes. If .Fa path is .No non- Ns Dv NULL , it must point to a buffer of at least .Dv NG_PATHSIZ bytes, which will be filled in (and .Dv NUL terminated) with the path to the node from which the message was received. .Pp The length of the control message is returned. A return value of zero indicates that the socket was closed. .Pp The .Fn NgAllocRecvMsg function works exactly like .Fn NgRecvMsg , except that the buffer for a message is dynamically allocated to guarantee that a message is not truncated. The size of the buffer is equal to the socket's receive buffer size. The caller is responsible for freeing the buffer when it is no longer required. .Pp The .Fn NgRecvAsciiMsg function works exactly like .Fn NgRecvMsg , except that after the message is received, any binary arguments are converted to .Tn ASCII by sending a .Dv NGM_BINARY2ASCII request back to the originating node. The result is the same as .Fn NgRecvMsg , with the exception that the reply arguments field will contain a .Dv NUL Ns -terminated .Tn ASCII version of the arguments (and the reply header argument length field will be adjusted). .Pp The .Fn NgAllocRecvAsciiMsg function works exactly like .Fn NgRecvAsciiMsg , except that the buffer for a message is dynamically allocated to guarantee that a message is not truncated. The size of the buffer is equal to the socket's receive buffer size. The caller is responsible for freeing the buffer when it is no longer required. .Pp The .Fn NgSendData function writes a data packet out on the specified hook of the node corresponding to data socket .Fa ds . The node must already be connected to some other node via that hook. .Pp The .Fn NgRecvData function reads the next data packet (of up to .Fa len bytes) received by the node corresponding to data socket .Fa ds and stores it in .Fa buf , which must be large enough to hold the entire packet. If .Fa hook is .No non- Ns Dv NULL , it must point to a buffer of at least .Dv NG_HOOKSIZ bytes, which will be filled in (and .Dv NUL terminated) with the name of the hook on which the data was received. .Pp The length of the packet is returned. A return value of zero indicates that the socket was closed. .Pp The .Fn NgAllocRecvData function works exactly like .Fn NgRecvData , except that the buffer for a data packet is dynamically allocated to guarantee that a data packet is not truncated. The size of the buffer is equal to the socket's receive buffer size. The caller is responsible for freeing the buffer when it is no longer required. .Pp The .Fn NgSetDebug and .Fn NgSetErrLog functions are used for debugging. The .Fn NgSetDebug function sets the debug level (if non-negative), and returns the old setting. Higher debug levels result in more verbosity. The default is zero. All debug and error messages are logged via the functions specified in the most recent call to .Fn NgSetErrLog . The default logging functions are .Xr vwarn 3 and .Xr vwarnx 3 . .Pp At debug level 3, the library attempts to display control message arguments in .Tn ASCII format; however, this results in additional messages being sent which may interfere with debugging. At even higher levels, even these additional messages will be displayed, etc. .Pp Note that .Xr select 2 can be used on the data and the control sockets to detect the presence of incoming data and control messages, respectively. Data and control packets are always written and read atomically, i.e., in one whole piece. .Pp User mode programs must be linked with the .Fl l Ns Li netgraph flag to link in this library. .Sh INITIALIZATION To enable netgraph in your kernel, either your kernel must be compiled with .Cd "options NETGRAPH" in the kernel configuration file, or else the .Xr netgraph 4 and .Xr ng_socket 4 KLD modules must have been loaded via .Xr kldload 8 . .Sh RETURN VALUES The .Fn NgSetDebug function returns the previous debug setting. .Pp The .Fn NgSetErrLog function has no return value. .Pp All other functions return \-1 if there was an error and set .Va errno accordingly. .Pp A return value of zero from .Fn NgRecvMsg or .Fn NgRecvData indicates that the netgraph socket has been closed. .Pp For .Fn NgSendAsciiMsg and .Fn NgRecvAsciiMsg , the following additional errors are possible: .Bl -tag -width Er .It Bq Er ENOSYS The node type does not know how to encode or decode the control message. .It Bq Er ERANGE The encoded or decoded arguments were too long for the supplied buffer. .It Bq Er ENOENT An unknown structure field was seen in an .Tn ASCII control message. .It Bq Er EALREADY The same structure field was specified twice in an .Tn ASCII control message. .It Bq Er EINVAL .Tn ASCII control message parse error or illegal value. .It Bq Er E2BIG ASCII control message array or fixed width string buffer overflow. .El .Sh SEE ALSO .Xr select 2 , .Xr socket 2 , .Xr warnx 3 , .Xr kld 4 , .Xr netgraph 4 , .Xr ng_socket 4 .Sh HISTORY The .Nm netgraph system was designed and first implemented at Whistle Communications, Inc.\& in a version of .Fx 2.2 customized for the Whistle InterJet. .Sh AUTHORS .An "Archie Cobbs" Aq archie@FreeBSD.org freebsd-libs-10.1~svn273304/lib/libnetgraph/debug.c0000644000000000000000000002153711316122231016571 0ustar /* * debug.c * * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, use and * redistribution of this software, in source or object code forms, with or * without modifications are expressly permitted by Whistle Communications; * provided, however, that: * 1. Any and all reproductions of the source or object code must include the * copyright notice above and the following disclaimer of warranties; and * 2. No rights are granted, in any manner or form, to use Whistle * Communications, Inc. trademarks, including the mark "WHISTLE * COMMUNICATIONS" on advertising, endorsements, or otherwise except as * such appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Archie Cobbs * * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include "netgraph.h" #include "internal.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WHISTLE #include #include #include #include #include #include #endif /* Global debug level */ int _gNgDebugLevel = 0; /* Debug printing functions */ void (*_NgLog) (const char *fmt,...) = warn; void (*_NgLogx) (const char *fmt,...) = warnx; /* Internal functions */ static const char *NgCookie(int cookie); /* Known typecookie list */ struct ng_cookie { int cookie; const char *type; }; #define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } /* List of known cookies */ static const struct ng_cookie cookies[] = { COOKIE(UI), COOKIE(ASYNC), COOKIE(ATMLLC), COOKIE(BPF), COOKIE(BRIDGE), COOKIE(CISCO), COOKIE(DEVICE), COOKIE(ECHO), COOKIE(EIFACE), COOKIE(ETF), COOKIE(ETHER), COOKIE(FEC), COOKIE(FRAMERELAY), COOKIE(GIF), COOKIE(GIF_DEMUX), COOKIE(GENERIC), COOKIE(HOLE), COOKIE(HUB), COOKIE(IFACE), COOKIE(IP_INPUT), COOKIE(IPFW), COOKIE(KSOCKET), COOKIE(L2TP), COOKIE(LMI), COOKIE(MPPC), COOKIE(NAT), COOKIE(ONE2MANY), COOKIE(PPP), COOKIE(PPPOE), COOKIE(PPTPGRE), COOKIE(RFC1490), COOKIE(SOCKET), COOKIE(SOURCE), COOKIE(SPLIT), COOKIE(SPPP), COOKIE(TCPMSS), COOKIE(TEE), COOKIE(TTY), COOKIE(VJC), COOKIE(VLAN), #ifdef WHISTLE COOKIE(DF), COOKIE(IPAC), COOKIE(TN), COOKIE(WFRA), #endif { 0, NULL } }; /* * Set debug level, ie, verbosity, if "level" is non-negative. * Returns old debug level. */ int NgSetDebug(int level) { int old = _gNgDebugLevel; if (level < 0) level = old; _gNgDebugLevel = level; return (old); } /* * Set debug logging functions. */ void NgSetErrLog(void (*log) (const char *fmt,...), void (*logx) (const char *fmt,...)) { _NgLog = log; _NgLogx = logx; } /* * Display a netgraph sockaddr */ void _NgDebugSockaddr(const struct sockaddr_ng *sg) { NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", sg->sg_family, sg->sg_len, sg->sg_data); } #define ARGS_BUFSIZE 2048 #define RECURSIVE_DEBUG_ADJUST 4 /* * Display a negraph message */ void _NgDebugMsg(const struct ng_mesg *msg, const char *path) { u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; struct ng_mesg *const req = (struct ng_mesg *)buf; struct ng_mesg *const bin = (struct ng_mesg *)req->data; int arglen, csock = -1; /* Display header stuff */ NGLOGX("NG_MESG :"); NGLOGX(" vers %d", msg->header.version); NGLOGX(" arglen %d", msg->header.arglen); NGLOGX(" flags %ld", msg->header.flags); NGLOGX(" token %lu", (u_long)msg->header.token); NGLOGX(" cookie %s (%d)", NgCookie(msg->header.typecookie), msg->header.typecookie); /* At lower debugging levels, skip ASCII translation */ if (_gNgDebugLevel <= 2) goto fail2; /* If path is not absolute, don't bother trying to use relative address on a different socket for the ASCII translation */ if (strchr(path, ':') == NULL) goto fail2; /* Get a temporary socket */ if (NgMkSockNode(NULL, &csock, NULL) < 0) goto fail; /* Copy binary message into request message payload */ arglen = msg->header.arglen; if (arglen > ARGS_BUFSIZE) arglen = ARGS_BUFSIZE; memcpy(bin, msg, sizeof(*msg) + arglen); bin->header.arglen = arglen; /* Lower debugging to avoid infinite recursion */ _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST; /* Ask the node to translate the binary message to ASCII for us */ if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) { _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; goto fail; } if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) { _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; goto fail; } /* Restore debugging level */ _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; /* Display command string and arguments */ NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); NGLOGX(" args %s", bin->data); goto done; fail: /* Just display binary version */ NGLOGX(" [error decoding message: %s]", strerror(errno)); fail2: NGLOGX(" cmd %d", msg->header.cmd); NGLOGX(" args (%d bytes)", msg->header.arglen); _NgDebugBytes((u_char *)msg->data, msg->header.arglen); done: if (csock != -1) (void)close(csock); } /* * Return the name of the node type corresponding to the cookie */ static const char * NgCookie(int cookie) { int k; for (k = 0; cookies[k].cookie != 0; k++) { if (cookies[k].cookie == cookie) return cookies[k].type; } return "??"; } /* * Dump bytes in hex */ void _NgDebugBytes(const u_char *ptr, int len) { char buf[100]; int k, count; #define BYPERLINE 16 for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { /* Do hex */ snprintf(buf, sizeof(buf), "%04x: ", count); for (k = 0; k < BYPERLINE; k++, count++) if (count < len) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%02x ", ptr[k]); else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); count -= BYPERLINE; /* Do ASCII */ for (k = 0; k < BYPERLINE; k++, count++) if (count < len) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c", isprint(ptr[k]) ? ptr[k] : '.'); else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); count -= BYPERLINE; /* Print it */ NGLOGX("%s", buf); } } freebsd-libs-10.1~svn273304/lib/libipx/0000755000000000000000000000000012421417235014330 5ustar freebsd-libs-10.1~svn273304/lib/libipx/Makefile0000644000000000000000000000023111317614257015772 0ustar # $FreeBSD$ LIB= ipx SHLIBDIR?= /lib SRCS= ipx_addr.c ipx_ntoa.c MAN= ipx.3 MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3 WARNS?= 2 .include freebsd-libs-10.1~svn273304/lib/libipx/ipx_ntoa.c0000644000000000000000000000565610550564616016340 0ustar /* * Copyright (c) 1986, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)ipx_ntoa.c"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include static char *spectHex(char *); char * ipx_ntoa(addr) struct ipx_addr addr; { static char obuf[40]; union { union ipx_net net_e; u_long long_e; } net; u_short port = htons(addr.x_port); char *cp; char *cp2; u_char *up = addr.x_host.c_host; u_char *uplim = up + 6; net.net_e = addr.x_net; sprintf(obuf, "%lx", (u_long)ntohl(net.long_e)); cp = spectHex(obuf); cp2 = cp + 1; while (*up==0 && up < uplim) up++; if (up == uplim) { if (port) { sprintf(cp, ".0"); cp += 2; } } else { sprintf(cp, ".%x", *up++); while (up < uplim) { while (*cp) cp++; sprintf(cp, "%02x", *up++); } cp = spectHex(cp2); } if (port) { sprintf(cp, ".%x", port); spectHex(cp + 1); } return (obuf); } static char * spectHex(p0) char *p0; { int ok = 0; int nonzero = 0; char *p = p0; for (; *p; p++) switch (*p) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': ok = 1; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': nonzero = 1; } if (nonzero && !ok) { *p++ = 'H'; *p = 0; } return (p); } freebsd-libs-10.1~svn273304/lib/libipx/ipx.30000644000000000000000000000746411436235001015221 0ustar .\" Copyright (c) 1986, 1991, 1993 .\" The Regents of the University of California. 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. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. .\" .\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt IPX 3 .Os .Sh NAME .Nm ipx_addr , .Nm ipx_ntoa .Nd IPX address conversion routines .Sh LIBRARY .Lb libipx .Sh SYNOPSIS .In sys/types.h .In netipx/ipx.h .Ft struct ipx_addr .Fn ipx_addr "const char *cp" .Ft char * .Fn ipx_ntoa "struct ipx_addr ipx" .Sh DESCRIPTION The routine .Fn ipx_addr interprets character strings representing .Tn IPX addresses, returning binary information suitable for use in system calls. The routine .Fn ipx_ntoa takes .Tn IPX addresses and returns .Tn ASCII strings representing the address in a notation in common use: .Bd -ragged -offset indent .. .Ed .Pp Trailing zero fields are suppressed, and each number is printed in hexadecimal, in a format suitable for input to .Fn ipx_addr . Any fields lacking super-decimal digits will have a trailing .Ql H appended. .Pp An effort has been made to ensure that .Fn ipx_addr be compatible with most formats in common use. It will first separate an address into 1 to 3 fields using a single delimiter chosen from period .Ql \&. , colon .Ql \&: or pound-sign .Ql \&# . Each field is then examined for byte separators (colon or period). If there are byte separators, each subfield separated is taken to be a small hexadecimal number, and the entirety is taken as a network-byte-ordered quantity to be zero extended in the high-network-order bytes. Next, the field is inspected for hyphens, in which case the field is assumed to be a number in decimal notation with hyphens separating the millennia. Next, the field is assumed to be a number: It is interpreted as hexadecimal if there is a leading .Ql 0x (as in C), a trailing .Ql H (as in Mesa), or there are any super-decimal digits present. It is interpreted as octal if there is a leading .Ql 0 and there are no super-octal digits. Otherwise, it is converted as a decimal number. .Sh RETURN VALUES None. (See .Sx BUGS . ) .Sh SEE ALSO .\" .Xr ns 4 , .Xr hosts 5 , .Xr networks 5 .Sh HISTORY The precursor .Fn ns_addr and .Fn ns_toa functions appeared in .Bx 4.3 . .Sh BUGS The string returned by .Fn ipx_ntoa resides in a static memory area. The function .Fn ipx_addr should diagnose improperly formed input, and there should be an unambiguous way to recognize this. freebsd-libs-10.1~svn273304/lib/libipx/ipx_addr.c0000644000000000000000000001311610550564616016277 0ustar /* * Copyright (c) 1986, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * J.Q. Johnson. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)ipx_addr.c"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include static struct ipx_addr addr, zero_addr; static void Field(), cvtbase(); struct ipx_addr ipx_addr(name) const char *name; { char separator; char *hostname, *socketname, *cp; char buf[50]; (void)strncpy(buf, name, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; /* * First, figure out what he intends as a field separator. * Despite the way this routine is written, the preferred * form 2-272.AA001234H.01777, i.e. XDE standard. * Great efforts are made to ensure backwards compatibility. */ if ( (hostname = strchr(buf, '#')) ) separator = '#'; else { hostname = strchr(buf, '.'); if ((cp = strchr(buf, ':')) && ((hostname && cp < hostname) || (hostname == 0))) { hostname = cp; separator = ':'; } else separator = '.'; } if (hostname) *hostname++ = 0; addr = zero_addr; Field(buf, addr.x_net.c_net, 4); if (hostname == 0) return (addr); /* No separator means net only */ socketname = strchr(hostname, separator); if (socketname) { *socketname++ = 0; Field(socketname, (u_char *)&addr.x_port, 2); } Field(hostname, addr.x_host.c_host, 6); return (addr); } static void Field(buf, out, len) char *buf; u_char *out; int len; { char *bp = buf; int i, ibase, base16 = 0, base10 = 0, clen = 0; int hb[6], *hp; char *fmt; /* * first try 2-273#2-852-151-014#socket */ if ((*buf != '-') && (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { cvtbase(1000L, 256, hb, i, out, len); return; } /* * try form 8E1#0.0.AA.0.5E.E6#socket */ if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { cvtbase(256L, 256, hb, i, out, len); return; } /* * try form 8E1#0:0:AA:0:5E:E6#socket */ if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { cvtbase(256L, 256, hb, i, out, len); return; } /* * This is REALLY stretching it but there was a * comma notation separating shorts -- definitely non-standard */ if (1 < (i = sscanf(buf,"%x,%x,%x", &hb[0], &hb[1], &hb[2]))) { hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); hb[2] = htons(hb[2]); cvtbase(65536L, 256, hb, i, out, len); return; } /* Need to decide if base 10, 16 or 8 */ while (*bp) switch (*bp++) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '-': break; case '8': case '9': base10 = 1; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': base16 = 1; break; case 'x': case 'X': *--bp = '0'; base16 = 1; break; case 'h': case 'H': base16 = 1; /* FALLTHROUGH */ default: *--bp = 0; /* Ends Loop */ } if (base16) { fmt = "%3x"; ibase = 4096; } else if (base10 == 0 && *buf == '0') { fmt = "%3o"; ibase = 512; } else { fmt = "%3d"; ibase = 1000; } for (bp = buf; *bp++; ) clen++; if (clen == 0) clen++; if (clen > 18) clen = 18; i = ((clen - 1) / 3) + 1; bp = clen + buf - 3; hp = hb + i - 1; while (hp > hb) { (void)sscanf(bp, fmt, hp); bp[0] = 0; hp--; bp -= 3; } (void)sscanf(buf, fmt, hp); cvtbase((long)ibase, 256, hb, i, out, len); } static void cvtbase(oldbase,newbase,input,inlen,result,reslen) long oldbase; int newbase; int input[]; int inlen; unsigned char result[]; int reslen; { int d, e; long sum; e = 1; while (e > 0 && reslen > 0) { d = 0; e = 0; sum = 0; /* long division: input=input/newbase */ while (d < inlen) { sum = sum*oldbase + (long) input[d]; e += (sum > 0); input[d++] = sum / newbase; sum %= newbase; } result[--reslen] = sum; /* accumulate remainder */ } for (d=0; d < reslen; d++) result[d] = 0; } freebsd-libs-10.1~svn273304/lib/libsbuf/0000755000000000000000000000000012421417270014466 5ustar freebsd-libs-10.1~svn273304/lib/libsbuf/Version.def0000644000000000000000000000006312131611762016572 0ustar # $FreeBSD$ FBSD_1.2 { }; FBSD_1.3 { } FBSD_1.2; freebsd-libs-10.1~svn273304/lib/libsbuf/Makefile0000644000000000000000000000032211564531166016133 0ustar # $FreeBSD$ LIB= sbuf SHLIBDIR?= /lib SRCS= subr_sbuf.c SHLIB_MAJOR = 6 SYMBOL_MAPS= ${.CURDIR}/Symbol.map VERSION_DEF= ${.CURDIR}/Version.def .PATH: ${.CURDIR}/../../sys/kern .include freebsd-libs-10.1~svn273304/lib/libsbuf/Symbol.map0000644000000000000000000000050012131611762016425 0ustar /* * $FreeBSD$ */ FBSD_1.2 { sbuf_new; sbuf_clear; sbuf_setpos; sbuf_bcat; sbuf_bcpy; sbuf_cat; sbuf_cpy; sbuf_printf; sbuf_vprintf; sbuf_putc; sbuf_set_drain; sbuf_trim; sbuf_error; sbuf_finish; sbuf_data; sbuf_len; sbuf_done; sbuf_delete; }; FBSD_1.3 { sbuf_start_section; sbuf_end_section; }; freebsd-libs-10.1~svn273304/lib/libjail/0000755000000000000000000000000012421417257014453 5ustar freebsd-libs-10.1~svn273304/lib/libjail/jail.c0000644000000000000000000006542512033357131015543 0ustar /*- * Copyright (c) 2009 James Gritton. * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include "jail.h" #define SJPARAM "security.jail.param" #define JPS_IN_ADDR 1 #define JPS_IN6_ADDR 2 #define ARRAY_SANITY 5 #define ARRAY_SLOP 5 static int jailparam_import_enum(const char **values, int nvalues, const char *valstr, size_t valsize, int *value); static int jailparam_type(struct jailparam *jp); static char *noname(const char *name); static char *nononame(const char *name); char jail_errmsg[JAIL_ERRMSGLEN]; static const char *bool_values[] = { "false", "true" }; static const char *jailsys_values[] = { "disable", "new", "inherit" }; /* * Import a null-terminated parameter list and set a jail with the flags * and parameters. */ int jail_setv(int flags, ...) { va_list ap, tap; struct jailparam *jp; const char *name, *value; int njp, jid; /* Create the parameter list and import the parameters. */ va_start(ap, flags); va_copy(tap, ap); for (njp = 0; va_arg(tap, char *) != NULL; njp++) (void)va_arg(tap, char *); va_end(tap); jp = alloca(njp * sizeof(struct jailparam)); for (njp = 0; (name = va_arg(ap, char *)) != NULL;) { value = va_arg(ap, char *); if (jailparam_init(jp + njp, name) < 0) goto error; if (jailparam_import(jp + njp++, value) < 0) goto error; } va_end(ap); jid = jailparam_set(jp, njp, flags); jailparam_free(jp, njp); return (jid); error: jailparam_free(jp, njp); va_end(ap); return (-1); } /* * Read a null-terminated parameter list, get the referenced jail, and export * the parameters to the list. */ int jail_getv(int flags, ...) { va_list ap, tap; struct jailparam *jp, *jp_lastjid, *jp_jid, *jp_name, *jp_key; char *valarg, *value; const char *name, *key_value, *lastjid_value, *jid_value, *name_value; int njp, i, jid; /* Create the parameter list and find the key. */ va_start(ap, flags); va_copy(tap, ap); for (njp = 0; va_arg(tap, char *) != NULL; njp++) (void)va_arg(tap, char *); va_end(tap); jp = alloca(njp * sizeof(struct jailparam)); va_copy(tap, ap); jp_lastjid = jp_jid = jp_name = NULL; lastjid_value = jid_value = name_value = NULL; for (njp = 0; (name = va_arg(tap, char *)) != NULL; njp++) { value = va_arg(tap, char *); if (jailparam_init(jp + njp, name) < 0) { va_end(tap); goto error; } if (!strcmp(jp[njp].jp_name, "lastjid")) { jp_lastjid = jp + njp; lastjid_value = value; } else if (!strcmp(jp[njp].jp_name, "jid")) { jp_jid = jp + njp; jid_value = value; } if (!strcmp(jp[njp].jp_name, "name")) { jp_name = jp + njp; name_value = value; } } va_end(tap); /* Import the key parameter. */ if (jp_lastjid != NULL) { jp_key = jp_lastjid; key_value = lastjid_value; } else if (jp_jid != NULL && strtol(jid_value, NULL, 10) != 0) { jp_key = jp_jid; key_value = jid_value; } else if (jp_name != NULL) { jp_key = jp_name; key_value = name_value; } else { strlcpy(jail_errmsg, "no jail specified", JAIL_ERRMSGLEN); errno = ENOENT; goto error; } if (jailparam_import(jp_key, key_value) < 0) goto error; /* Get the jail and export the parameters. */ jid = jailparam_get(jp, njp, flags); if (jid < 0) goto error; for (i = 0; i < njp; i++) { (void)va_arg(ap, char *); valarg = va_arg(ap, char *); if (jp + i != jp_key) { /* It's up to the caller to ensure there's room. */ if ((jp[i].jp_ctltype & CTLTYPE) == CTLTYPE_STRING) strcpy(valarg, jp[i].jp_value); else { value = jailparam_export(jp + i); if (value == NULL) goto error; strcpy(valarg, value); free(value); } } } jailparam_free(jp, njp); va_end(ap); return (jid); error: jailparam_free(jp, njp); va_end(ap); return (-1); } /* * Return a list of all known parameters. */ int jailparam_all(struct jailparam **jpp) { struct jailparam *jp, *tjp; size_t mlen1, mlen2, buflen; int njp, nlist; int mib1[CTL_MAXNAME], mib2[CTL_MAXNAME - 2]; char buf[MAXPATHLEN]; njp = 0; nlist = 32; jp = malloc(nlist * sizeof(*jp)); if (jp == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } mib1[0] = 0; mib1[1] = 2; mlen1 = CTL_MAXNAME - 2; if (sysctlnametomib(SJPARAM, mib1 + 2, &mlen1) < 0) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctlnametomib(" SJPARAM "): %s", strerror(errno)); goto error; } for (;; njp++) { /* Get the next parameter. */ mlen2 = sizeof(mib2); if (sysctl(mib1, mlen1 + 2, mib2, &mlen2, NULL, 0) < 0) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(0.2): %s", strerror(errno)); goto error; } if (mib2[0] != mib1[2] || mib2[1] != mib1[3] || mib2[2] != mib1[4]) break; /* Convert it to an ascii name. */ memcpy(mib1 + 2, mib2, mlen2); mlen1 = mlen2 / sizeof(int); mib1[1] = 1; buflen = sizeof(buf); if (sysctl(mib1, mlen1 + 2, buf, &buflen, NULL, 0) < 0) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(0.1): %s", strerror(errno)); goto error; } if (buf[buflen - 2] == '.') buf[buflen - 2] = '\0'; /* Add the parameter to the list */ if (njp >= nlist) { nlist *= 2; tjp = realloc(jp, nlist * sizeof(*jp)); if (tjp == NULL) goto error; jp = tjp; } if (jailparam_init(jp + njp, buf + sizeof(SJPARAM)) < 0) goto error; mib1[1] = 2; } jp = realloc(jp, njp * sizeof(*jp)); *jpp = jp; return (njp); error: jailparam_free(jp, njp); free(jp); return (-1); } /* * Clear a jail parameter and copy in its name. */ int jailparam_init(struct jailparam *jp, const char *name) { memset(jp, 0, sizeof(*jp)); jp->jp_name = strdup(name); if (jp->jp_name == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } if (jailparam_type(jp) < 0) { jailparam_free(jp, 1); jp->jp_name = NULL; jp->jp_value = NULL; return (-1); } return (0); } /* * Put a name and value into a jail parameter element, converting the value * to internal form. */ int jailparam_import(struct jailparam *jp, const char *value) { char *p, *ep, *tvalue; const char *avalue; int i, nval, fw; if (value == NULL) return (0); if ((jp->jp_ctltype & CTLTYPE) == CTLTYPE_STRING) { jp->jp_value = strdup(value); if (jp->jp_value == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } return (0); } nval = 1; if (jp->jp_elemlen) { if (value[0] == '\0' || (value[0] == '-' && value[1] == '\0')) { jp->jp_value = strdup(""); if (jp->jp_value == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } jp->jp_valuelen = 0; return (0); } for (p = strchr(value, ','); p; p = strchr(p + 1, ',')) nval++; jp->jp_valuelen = jp->jp_elemlen * nval; } jp->jp_value = malloc(jp->jp_valuelen); if (jp->jp_value == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } avalue = value; for (i = 0; i < nval; i++) { fw = nval == 1 ? strlen(avalue) : strcspn(avalue, ","); switch (jp->jp_ctltype & CTLTYPE) { case CTLTYPE_INT: if (jp->jp_flags & (JP_BOOL | JP_NOBOOL)) { if (!jailparam_import_enum(bool_values, 2, avalue, fw, &((int *)jp->jp_value)[i])) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "%s: " "unknown boolean value \"%.*s\"", jp->jp_name, fw, avalue); errno = EINVAL; goto error; } break; } if (jp->jp_flags & JP_JAILSYS) { /* * Allow setting a jailsys parameter to "new" * in a booleanesque fashion. */ if (value[0] == '\0') ((int *)jp->jp_value)[i] = JAIL_SYS_NEW; else if (!jailparam_import_enum(jailsys_values, sizeof(jailsys_values) / sizeof(jailsys_values[0]), avalue, fw, &((int *)jp->jp_value)[i])) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "%s: " "unknown jailsys value \"%.*s\"", jp->jp_name, fw, avalue); errno = EINVAL; goto error; } break; } ((int *)jp->jp_value)[i] = strtol(avalue, &ep, 10); integer_test: if (ep != avalue + fw) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "%s: non-integer value \"%.*s\"", jp->jp_name, fw, avalue); errno = EINVAL; goto error; } break; case CTLTYPE_UINT: ((unsigned *)jp->jp_value)[i] = strtoul(avalue, &ep, 10); goto integer_test; case CTLTYPE_LONG: ((long *)jp->jp_value)[i] = strtol(avalue, &ep, 10); goto integer_test; case CTLTYPE_ULONG: ((unsigned long *)jp->jp_value)[i] = strtoul(avalue, &ep, 10); goto integer_test; case CTLTYPE_S64: ((int64_t *)jp->jp_value)[i] = strtoimax(avalue, &ep, 10); goto integer_test; case CTLTYPE_U64: ((uint64_t *)jp->jp_value)[i] = strtoumax(avalue, &ep, 10); goto integer_test; case CTLTYPE_STRUCT: tvalue = alloca(fw + 1); strlcpy(tvalue, avalue, fw + 1); switch (jp->jp_structtype) { case JPS_IN_ADDR: if (inet_pton(AF_INET, tvalue, &((struct in_addr *)jp->jp_value)[i]) != 1) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "%s: not an IPv4 address: %s", jp->jp_name, tvalue); errno = EINVAL; goto error; } break; case JPS_IN6_ADDR: if (inet_pton(AF_INET6, tvalue, &((struct in6_addr *)jp->jp_value)[i]) != 1) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "%s: not an IPv6 address: %s", jp->jp_name, tvalue); errno = EINVAL; goto error; } break; default: goto unknown_type; } break; default: unknown_type: snprintf(jail_errmsg, JAIL_ERRMSGLEN, "unknown type for %s", jp->jp_name); errno = ENOENT; goto error; } avalue += fw + 1; } return (0); error: free(jp->jp_value); jp->jp_value = NULL; return (-1); } static int jailparam_import_enum(const char **values, int nvalues, const char *valstr, size_t valsize, int *value) { char *ep; int i; for (i = 0; i < nvalues; i++) if (valsize == strlen(values[i]) && !strncasecmp(valstr, values[i], valsize)) { *value = i; return 1; } *value = strtol(valstr, &ep, 10); return (ep == valstr + valsize); } /* * Put a name and value into a jail parameter element, copying the value * but not altering it. */ int jailparam_import_raw(struct jailparam *jp, void *value, size_t valuelen) { jp->jp_value = value; jp->jp_valuelen = valuelen; jp->jp_flags |= JP_RAWVALUE; return (0); } /* * Run the jail_set and jail_get system calls on a parameter list. */ int jailparam_set(struct jailparam *jp, unsigned njp, int flags) { struct iovec *jiov; char *nname; int i, jid, bool0; unsigned j; jiov = alloca(sizeof(struct iovec) * 2 * (njp + 1)); bool0 = 0; for (i = j = 0; j < njp; j++) { jiov[i].iov_base = jp[j].jp_name; jiov[i].iov_len = strlen(jp[j].jp_name) + 1; i++; if (jp[j].jp_flags & (JP_BOOL | JP_NOBOOL)) { /* * Set booleans without values. If one has a value of * zero, change it to (or from) its "no" counterpart. */ jiov[i].iov_base = NULL; jiov[i].iov_len = 0; if (jp[j].jp_value != NULL && jp[j].jp_valuelen == sizeof(int) && !*(int *)jp[j].jp_value) { bool0 = 1; nname = jp[j].jp_flags & JP_BOOL ? noname(jp[j].jp_name) : nononame(jp[j].jp_name); if (nname == NULL) { njp = j; jid = -1; goto done; } jiov[i - 1].iov_base = nname; jiov[i - 1].iov_len = strlen(nname) + 1; } } else { /* * Try to fill in missing values with an empty string. */ if (jp[j].jp_value == NULL && jp[j].jp_valuelen > 0 && jailparam_import(jp + j, "") < 0) { njp = j; jid = -1; goto done; } jiov[i].iov_base = jp[j].jp_value; jiov[i].iov_len = (jp[j].jp_ctltype & CTLTYPE) == CTLTYPE_STRING ? strlen(jp[j].jp_value) + 1 : jp[j].jp_valuelen; } i++; } *(const void **)&jiov[i].iov_base = "errmsg"; jiov[i].iov_len = sizeof("errmsg"); i++; jiov[i].iov_base = jail_errmsg; jiov[i].iov_len = JAIL_ERRMSGLEN; i++; jail_errmsg[0] = 0; jid = jail_set(jiov, i, flags); if (jid < 0 && !jail_errmsg[0]) snprintf(jail_errmsg, sizeof(jail_errmsg), "jail_set: %s", strerror(errno)); done: if (bool0) for (j = 0; j < njp; j++) if ((jp[j].jp_flags & (JP_BOOL | JP_NOBOOL)) && jp[j].jp_value != NULL && jp[j].jp_valuelen == sizeof(int) && !*(int *)jp[j].jp_value) free(jiov[j * 2].iov_base); return (jid); } int jailparam_get(struct jailparam *jp, unsigned njp, int flags) { struct iovec *jiov; struct jailparam *jp_lastjid, *jp_jid, *jp_name, *jp_key; int i, ai, ki, jid, arrays, sanity; unsigned j; /* * Get the types for all parameters. * Find the key and any array parameters. */ jiov = alloca(sizeof(struct iovec) * 2 * (njp + 1)); jp_lastjid = jp_jid = jp_name = NULL; arrays = 0; for (ai = j = 0; j < njp; j++) { if (!strcmp(jp[j].jp_name, "lastjid")) jp_lastjid = jp + j; else if (!strcmp(jp[j].jp_name, "jid")) jp_jid = jp + j; else if (!strcmp(jp[j].jp_name, "name")) jp_name = jp + j; else if (jp[j].jp_elemlen && !(jp[j].jp_flags & JP_RAWVALUE)) { arrays = 1; jiov[ai].iov_base = jp[j].jp_name; jiov[ai].iov_len = strlen(jp[j].jp_name) + 1; ai++; jiov[ai].iov_base = NULL; jiov[ai].iov_len = 0; ai++; } } jp_key = jp_lastjid ? jp_lastjid : jp_jid && jp_jid->jp_valuelen == sizeof(int) && jp_jid->jp_value && *(int *)jp_jid->jp_value ? jp_jid : jp_name; if (jp_key == NULL || jp_key->jp_value == NULL) { strlcpy(jail_errmsg, "no jail specified", JAIL_ERRMSGLEN); errno = ENOENT; return (-1); } ki = ai; jiov[ki].iov_base = jp_key->jp_name; jiov[ki].iov_len = strlen(jp_key->jp_name) + 1; ki++; jiov[ki].iov_base = jp_key->jp_value; jiov[ki].iov_len = (jp_key->jp_ctltype & CTLTYPE) == CTLTYPE_STRING ? strlen(jp_key->jp_value) + 1 : jp_key->jp_valuelen; ki++; *(const void **)&jiov[ki].iov_base = "errmsg"; jiov[ki].iov_len = sizeof("errmsg"); ki++; jiov[ki].iov_base = jail_errmsg; jiov[ki].iov_len = JAIL_ERRMSGLEN; ki++; jail_errmsg[0] = 0; if (arrays && jail_get(jiov, ki, flags) < 0) { if (!jail_errmsg[0]) snprintf(jail_errmsg, sizeof(jail_errmsg), "jail_get: %s", strerror(errno)); return (-1); } /* Allocate storage for all parameters. */ for (ai = j = 0, i = ki; j < njp; j++) { if (jp[j].jp_elemlen && !(jp[j].jp_flags & JP_RAWVALUE)) { ai++; jiov[ai].iov_len += jp[j].jp_elemlen * ARRAY_SLOP; if (jp[j].jp_valuelen >= jiov[ai].iov_len) jiov[ai].iov_len = jp[j].jp_valuelen; else { jp[j].jp_valuelen = jiov[ai].iov_len; if (jp[j].jp_value != NULL) free(jp[j].jp_value); jp[j].jp_value = malloc(jp[j].jp_valuelen); if (jp[j].jp_value == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } } jiov[ai].iov_base = jp[j].jp_value; memset(jiov[ai].iov_base, 0, jiov[ai].iov_len); ai++; } else if (jp + j != jp_key) { jiov[i].iov_base = jp[j].jp_name; jiov[i].iov_len = strlen(jp[j].jp_name) + 1; i++; if (jp[j].jp_value == NULL && !(jp[j].jp_flags & JP_RAWVALUE)) { jp[j].jp_value = malloc(jp[j].jp_valuelen); if (jp[j].jp_value == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } } jiov[i].iov_base = jp[j].jp_value; jiov[i].iov_len = jp[j].jp_valuelen; memset(jiov[i].iov_base, 0, jiov[i].iov_len); i++; } } /* * Get the prison. If there are array elements, retry a few times * in case their sizes changed from under us. */ for (sanity = 0;; sanity++) { jid = jail_get(jiov, i, flags); if (jid >= 0 || !arrays || sanity == ARRAY_SANITY || errno != EINVAL || jail_errmsg[0]) break; for (ai = j = 0; j < njp; j++) { if (jp[j].jp_elemlen && !(jp[j].jp_flags & JP_RAWVALUE)) { ai++; jiov[ai].iov_base = NULL; jiov[ai].iov_len = 0; ai++; } } if (jail_get(jiov, ki, flags) < 0) break; for (ai = j = 0; j < njp; j++) { if (jp[j].jp_elemlen && !(jp[j].jp_flags & JP_RAWVALUE)) { ai++; jiov[ai].iov_len += jp[j].jp_elemlen * ARRAY_SLOP; if (jp[j].jp_valuelen >= jiov[ai].iov_len) jiov[ai].iov_len = jp[j].jp_valuelen; else { jp[j].jp_valuelen = jiov[ai].iov_len; if (jp[j].jp_value != NULL) free(jp[j].jp_value); jp[j].jp_value = malloc(jiov[ai].iov_len); if (jp[j].jp_value == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (-1); } } jiov[ai].iov_base = jp[j].jp_value; memset(jiov[ai].iov_base, 0, jiov[ai].iov_len); ai++; } } } if (jid < 0 && !jail_errmsg[0]) snprintf(jail_errmsg, sizeof(jail_errmsg), "jail_get: %s", strerror(errno)); for (ai = j = 0, i = ki; j < njp; j++) { if (jp[j].jp_elemlen && !(jp[j].jp_flags & JP_RAWVALUE)) { ai++; jp[j].jp_valuelen = jiov[ai].iov_len; ai++; } else if (jp + j != jp_key) { i++; jp[j].jp_valuelen = jiov[i].iov_len; i++; } } return (jid); } /* * Convert a jail parameter's value to external form. */ char * jailparam_export(struct jailparam *jp) { size_t *valuelens; char *value, *tvalue, **values; size_t valuelen; int i, nval, ival; char valbuf[INET6_ADDRSTRLEN]; if ((jp->jp_ctltype & CTLTYPE) == CTLTYPE_STRING) { value = strdup(jp->jp_value); if (value == NULL) strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (value); } nval = jp->jp_elemlen ? jp->jp_valuelen / jp->jp_elemlen : 1; if (nval == 0) { value = strdup(""); if (value == NULL) strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (value); } values = alloca(nval * sizeof(char *)); valuelens = alloca(nval * sizeof(size_t)); valuelen = 0; for (i = 0; i < nval; i++) { switch (jp->jp_ctltype & CTLTYPE) { case CTLTYPE_INT: ival = ((int *)jp->jp_value)[i]; if ((jp->jp_flags & (JP_BOOL | JP_NOBOOL)) && (unsigned)ival < 2) { strlcpy(valbuf, bool_values[ival], sizeof(valbuf)); break; } if ((jp->jp_flags & JP_JAILSYS) && (unsigned)ival < sizeof(jailsys_values) / sizeof(jailsys_values[0])) { strlcpy(valbuf, jailsys_values[ival], sizeof(valbuf)); break; } snprintf(valbuf, sizeof(valbuf), "%d", ival); break; case CTLTYPE_UINT: snprintf(valbuf, sizeof(valbuf), "%u", ((unsigned *)jp->jp_value)[i]); break; case CTLTYPE_LONG: snprintf(valbuf, sizeof(valbuf), "%ld", ((long *)jp->jp_value)[i]); break; case CTLTYPE_ULONG: snprintf(valbuf, sizeof(valbuf), "%lu", ((unsigned long *)jp->jp_value)[i]); break; case CTLTYPE_S64: snprintf(valbuf, sizeof(valbuf), "%jd", (intmax_t)((int64_t *)jp->jp_value)[i]); break; case CTLTYPE_U64: snprintf(valbuf, sizeof(valbuf), "%ju", (uintmax_t)((uint64_t *)jp->jp_value)[i]); break; case CTLTYPE_STRUCT: switch (jp->jp_structtype) { case JPS_IN_ADDR: if (inet_ntop(AF_INET, &((struct in_addr *)jp->jp_value)[i], valbuf, sizeof(valbuf)) == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (NULL); } break; case JPS_IN6_ADDR: if (inet_ntop(AF_INET6, &((struct in6_addr *)jp->jp_value)[i], valbuf, sizeof(valbuf)) == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (NULL); } break; default: goto unknown_type; } break; default: unknown_type: snprintf(jail_errmsg, JAIL_ERRMSGLEN, "unknown type for %s", jp->jp_name); errno = ENOENT; return (NULL); } valuelens[i] = strlen(valbuf) + 1; valuelen += valuelens[i]; values[i] = alloca(valuelens[i]); strcpy(values[i], valbuf); } value = malloc(valuelen); if (value == NULL) strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); else { tvalue = value; for (i = 0; i < nval; i++) { strcpy(tvalue, values[i]); if (i < nval - 1) { tvalue += valuelens[i]; tvalue[-1] = ','; } } } return (value); } /* * Free the contents of a jail parameter list (but not the list itself). */ void jailparam_free(struct jailparam *jp, unsigned njp) { unsigned j; for (j = 0; j < njp; j++) { free(jp[j].jp_name); if (!(jp[j].jp_flags & JP_RAWVALUE)) free(jp[j].jp_value); } } /* * Find a parameter's type and size from its MIB. */ static int jailparam_type(struct jailparam *jp) { char *p, *name, *nname; size_t miblen, desclen; int i, isarray; struct { int i; char s[MAXPATHLEN]; } desc; int mib[CTL_MAXNAME]; /* The "lastjid" parameter isn't real. */ name = jp->jp_name; if (!strcmp(name, "lastjid")) { jp->jp_valuelen = sizeof(int); jp->jp_ctltype = CTLTYPE_INT | CTLFLAG_WR; return (0); } /* Find the sysctl that describes the parameter. */ mib[0] = 0; mib[1] = 3; snprintf(desc.s, sizeof(desc.s), SJPARAM ".%s", name); miblen = sizeof(mib) - 2 * sizeof(int); if (sysctl(mib, 2, mib + 2, &miblen, desc.s, strlen(desc.s)) < 0) { if (errno != ENOENT) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(0.3.%s): %s", name, strerror(errno)); return (-1); } /* * The parameter probably doesn't exist. But it might be * the "no" counterpart to a boolean. */ nname = nononame(name); if (nname == NULL) { unknown_parameter: snprintf(jail_errmsg, JAIL_ERRMSGLEN, "unknown parameter: %s", jp->jp_name); errno = ENOENT; return (-1); } name = alloca(strlen(nname) + 1); strcpy(name, nname); free(nname); snprintf(desc.s, sizeof(desc.s), SJPARAM ".%s", name); miblen = sizeof(mib) - 2 * sizeof(int); if (sysctl(mib, 2, mib + 2, &miblen, desc.s, strlen(desc.s)) < 0) goto unknown_parameter; jp->jp_flags |= JP_NOBOOL; } mib_desc: mib[1] = 4; desclen = sizeof(desc); if (sysctl(mib, (miblen / sizeof(int)) + 2, &desc, &desclen, NULL, 0) < 0) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(0.4.%s): %s", name, strerror(errno)); return (-1); } jp->jp_ctltype = desc.i; /* If this came from removing a "no", it better be a boolean. */ if (jp->jp_flags & JP_NOBOOL) { if ((desc.i & CTLTYPE) == CTLTYPE_INT && desc.s[0] == 'B') { jp->jp_valuelen = sizeof(int); return (0); } else if ((desc.i & CTLTYPE) != CTLTYPE_NODE) goto unknown_parameter; } /* See if this is an array type. */ p = strchr(desc.s, '\0'); isarray = 0; if (p - 2 < desc.s || strcmp(p - 2, ",a")) isarray = 0; else { isarray = 1; p[-2] = 0; } /* Look for types we understand. */ switch (desc.i & CTLTYPE) { case CTLTYPE_INT: if (desc.s[0] == 'B') jp->jp_flags |= JP_BOOL; else if (!strcmp(desc.s, "E,jailsys")) jp->jp_flags |= JP_JAILSYS; case CTLTYPE_UINT: jp->jp_valuelen = sizeof(int); break; case CTLTYPE_LONG: case CTLTYPE_ULONG: jp->jp_valuelen = sizeof(long); break; case CTLTYPE_S64: case CTLTYPE_U64: jp->jp_valuelen = sizeof(int64_t); break; case CTLTYPE_STRING: desc.s[0] = 0; desclen = sizeof(desc.s); if (sysctl(mib + 2, miblen / sizeof(int), desc.s, &desclen, NULL, 0) < 0) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(" SJPARAM ".%s): %s", name, strerror(errno)); return (-1); } jp->jp_valuelen = strtoul(desc.s, NULL, 10); break; case CTLTYPE_STRUCT: if (!strcmp(desc.s, "S,in_addr")) { jp->jp_structtype = JPS_IN_ADDR; jp->jp_valuelen = sizeof(struct in_addr); } else if (!strcmp(desc.s, "S,in6_addr")) { jp->jp_structtype = JPS_IN6_ADDR; jp->jp_valuelen = sizeof(struct in6_addr); } else { desclen = 0; if (sysctl(mib + 2, miblen / sizeof(int), NULL, &jp->jp_valuelen, NULL, 0) < 0) { snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(" SJPARAM ".%s): %s", name, strerror(errno)); return (-1); } } break; case CTLTYPE_NODE: /* * A node might be described by an empty-named child, * which would be immediately before or after the node itself. */ mib[1] = 1; miblen += sizeof(int); for (i = -1; i <= 1; i += 2) { mib[(miblen / sizeof(int)) + 1] = mib[(miblen / sizeof(int))] + i; desclen = sizeof(desc.s); if (sysctl(mib, (miblen / sizeof(int)) + 2, desc.s, &desclen, NULL, 0) < 0) { if (errno == ENOENT) continue; snprintf(jail_errmsg, JAIL_ERRMSGLEN, "sysctl(0.1): %s", strerror(errno)); return (-1); } if (desclen == sizeof(SJPARAM) + strlen(name) + 2 && memcmp(SJPARAM ".", desc.s, sizeof(SJPARAM)) == 0 && memcmp(name, desc.s + sizeof(SJPARAM), desclen - sizeof(SJPARAM) - 2) == 0 && desc.s[desclen - 2] == '.') goto mib_desc; } goto unknown_parameter; default: snprintf(jail_errmsg, JAIL_ERRMSGLEN, "unknown type for %s", jp->jp_name); errno = ENOENT; return (-1); } if (isarray) { jp->jp_elemlen = jp->jp_valuelen; jp->jp_valuelen = 0; } return (0); } /* * Change a boolean parameter name into its "no" counterpart or vice versa. */ static char * noname(const char *name) { char *nname, *p; nname = malloc(strlen(name) + 3); if (nname == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (NULL); } p = strrchr(name, '.'); if (p != NULL) sprintf(nname, "%.*s.no%s", (int)(p - name), name, p + 1); else sprintf(nname, "no%s", name); return (nname); } static char * nononame(const char *name) { char *p, *nname; p = strrchr(name, '.'); if (strncmp(p ? p + 1 : name, "no", 2)) { snprintf(jail_errmsg, sizeof(jail_errmsg), "mismatched boolean: %s", name); errno = EINVAL; return (NULL); } nname = malloc(strlen(name) - 1); if (nname == NULL) { strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); return (NULL); } if (p != NULL) sprintf(nname, "%.*s.%s", (int)(p - name), name, p + 3); else strcpy(nname, name + 2); return (nname); } freebsd-libs-10.1~svn273304/lib/libjail/Makefile0000644000000000000000000000105211317614257016113 0ustar # $FreeBSD$ LIB= jail SHLIBDIR?= /lib SHLIB_MAJOR= 1 SRCS= jail.c jail_getid.c INCS= jail.h MAN= jail.3 MLINKS+=jail.3 jail_getid.3 MLINKS+=jail.3 jail_getname.3 MLINKS+=jail.3 jail_getv.3 MLINKS+=jail.3 jail_setv.3 MLINKS+=jail.3 jailparam.3 MLINKS+=jail.3 jailparam_all.3 MLINKS+=jail.3 jailparam_init.3 MLINKS+=jail.3 jailparam_import.3 MLINKS+=jail.3 jailparam_import_raw.3 MLINKS+=jail.3 jailparam_get.3 MLINKS+=jail.3 jailparam_set.3 MLINKS+=jail.3 jailparam_export.3 MLINKS+=jail.3 jailparam_free.3 CFLAGS+=-I${.CURDIR} .include freebsd-libs-10.1~svn273304/lib/libjail/jail.30000644000000000000000000001551511453610425015461 0ustar .\" Copyright (c) 2009 James Gritton. .\" 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. .\" .\" $FreeBSD$ .\" .Dd August 31, 2010 .Dt JAIL 3 .Os .Sh NAME .Nm jail_getid , .Nm jail_getname , .Nm jail_setv , .Nm jail_getv , .Nm jailparam_all , .Nm jailparam_init , .Nm jailparam_import , .Nm jailparam_import_raw , .Nm jailparam_set , .Nm jailparam_get , .Nm jailparam_export , .Nm jailparam_free .Nd create and manage system jails .Sh LIBRARY .Lb libjail .Sh SYNOPSIS .In sys/param.h .In sys/jail.h .In jail.h .Vt extern char jail_errmsg[] ; .Ft int .Fn jail_getid "const char *name" .Ft char * .Fn jail_getname "int jid" .Ft int .Fn jail_setv "int flags" ... .Ft int .Fn jail_getv "int flags" ... .Ft int .Fn jailparam_all "struct jailparam **jpp" .Ft int .Fn jailparam_init "struct jailparam *jp" "const char *name" .Ft int .Fn jailparam_import "struct jailparam *jp" "const char *value" .Ft int .Fn jailparam_import_raw "struct jailparam *jp" "void *value" "size_t valuelen" .Ft int .Fn jailparam_set "struct jailparam *jp" "unsigned njp" "int flags" .Ft int .Fn jailparam_get "struct jailparam *jp" "unsigned njp" "int flags" .Ft char * .Fn jailparam_export "struct jailparam *jp" .Ft void .Fn jailparam_free "struct jailparam *jp" "unsigned njp" .Sh DESCRIPTION The .Nm jail library is an interface to the .Xr jail_set 2 and .Xr jail_get 2 system calls, and the .Va security.jail.param MIB entries. It simplifies the conversion of prison parameters between internal and string formats, allowing the setting and querying of prisons without knowing the parameter formats. .Pp The .Fn jail_getid function returns the JID of the jail identified by .Fa name , or \-1 if the jail does not exist. .Pp The .Fn jail_getname function returns the name of the jail identified by .Fa jid , or .Dv NULL if the jail does not exist. .Pp The .Fn jail_setv function takes a null-terminated list of name and value strings, and passes it to .Xr jail_set 2 . .Pp The .Fn jail_getv function takes a null-terminated list of name and value strings, and passes it to .Xr jail_get 2 . It is the caller's responsibility to ensure that the value strings point to buffers large enough to hold the string representation of the returned parameters. .Pp The .Fn jailparam_all function sets .Fa jpp to a list of all known jail parameters, and returns the number of parameters. The list should later be freed with .Fn jailparam_free and .Xr free 3 . .Pp The .Fn jailparam_init function clears a parameter record and copies the .Fa name to it. After use, it should be freed with .Fn jailparam_free . .Pp The .Fn jailparam_import function adds a .Fa value to a parameter record, converting it from a string to its native form. The .Fn jailparam_import_raw function adds a value without performing any conversion. .Pp The .Fn jailparam_set function passes a list of parameters to .Xr jail_set 2 . The parameters are assumed to have been created with .Fn jailparam_init and .Fn jailparam_import . .Pp The .Fn jailparam_get function passes a list of parameters to .Xr jail_get 2 . The parameters are assumed to have been created with .Fn jailparam_init or .Fn jailparam_list , with one parameter (the key) having been given a value with .Fn jailparam_import . .Pp The .Fn jailparam_export function returns the string equivalent of a parameter value. The returned string should be freed after use. .Pp The .Fn jailparam_free function frees the stored names and values in a parameter list. If the list itself came from .Fn jailparam_all , it should be freed as well. .Sh RETURN VALUES The .Fn jail_getid , .Fn jail_setv , .Fn jail_getv , .Fn jailparam_set and .Fn jailparam_get functions return a JID on success, or \-1 on error. .Pp The .Fn jail_getname and .Fn jailparam_export functions return a dynamically allocated string on success, or .Dv NULL on error. .Pp The .Fn jailparam_all function returns the number of parameters on success, or \-1 on error. .Pp The .Fn jailparam_init , .Fn jailparam_import and .Fn jailparam_import_raw functions return 0 on success, or \-1 on error. .Pp Whenever an error is returned, .Va errno is set, and the global string .Va jail_errmsg contains a description of the error, possibly from .Xr jail_set 2 or .Xr jail_get 2 . .Sh EXAMPLES Set the hostname of jail .Dq foo to .Dq foo.bar : .Bd -literal -offset indent jail_setv(JAIL_UPDATE, "name", "foo", "host.hostname", "foo.bar", NULL); .Ed .Pp OR: .Bd -literal -offset indent struct jailparam params[2]; jailparam_init(¶ms[0], "name"); jailparam_import(¶ms[0], "foo"); jailparam_init(¶ms[1], "host.hostname"); jailparam_import(¶ms[1], "foo.bar"); jailparam_set(params, 2, JAIL_UPDATE); jailparam_free(params, 2); .Ed .Pp Retrieve the hostname of jail .Dq foo : .Bd -literal -offset indent char hostname[MAXHOSTNAMELEN]; jail_getv(0, "name", "foo", "host.hostname", hostname, NULL); .Ed .Pp OR: .Bd -literal -offset indent struct jailparam params[2]; jailparam_init(¶ms[0], "name"); jailparam_import(¶ms[0], "foo"); jailparam_init(¶ms[1], "host.hostname"); jailparam_get(params, 2, 0); hostname = jailparam_export(¶ms[1]); jailparam_free(params, 2); \&... free(hostname); .Ed .Sh ERRORS The .Nm jail functions may return errors from .Xr jail_set 2 , .Xr jail_get 2 , .Xr malloc 3 or .Xr sysctl 3 . In addition, the following errors are possible: .Bl -tag -width Er .It Bq Er EINVAL A parameter value cannot be converted from the passed string to its internal form. .It Bq Er ENOENT The named parameter does not exist. .It Bq Er ENOENT A parameter is of an unknown type. .El .Sh SEE ALSO .Xr jail 2 , .Xr sysctl 3 , .Xr jail 8 .Sh HISTORY The .Nm jail library first appeared in .Fx 8.0 . .Sh AUTHORS .An James Gritton freebsd-libs-10.1~svn273304/lib/libjail/jail_getid.c0000644000000000000000000000621511417657675016734 0ustar /*- * Copyright (c) 2009 James Gritton. * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "jail.h" /* * Return the JID corresponding to a jail name. */ int jail_getid(const char *name) { char *ep; int jid; struct iovec jiov[4]; jid = strtoul(name, &ep, 10); if (*name && !*ep) return jid; *(const void **)&jiov[0].iov_base = "name"; jiov[0].iov_len = sizeof("name"); jiov[1].iov_len = strlen(name) + 1; jiov[1].iov_base = alloca(jiov[1].iov_len); strcpy(jiov[1].iov_base, name); *(const void **)&jiov[2].iov_base = "errmsg"; jiov[2].iov_len = sizeof("errmsg"); jiov[3].iov_base = jail_errmsg; jiov[3].iov_len = JAIL_ERRMSGLEN; jail_errmsg[0] = 0; jid = jail_get(jiov, 4, 0); if (jid < 0 && !jail_errmsg[0]) snprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno)); return jid; } /* * Return the name corresponding to a JID. */ char * jail_getname(int jid) { struct iovec jiov[6]; char *name; char namebuf[MAXHOSTNAMELEN]; *(const void **)&jiov[0].iov_base = "jid"; jiov[0].iov_len = sizeof("jid"); jiov[1].iov_base = &jid; jiov[1].iov_len = sizeof(jid); *(const void **)&jiov[2].iov_base = "name"; jiov[2].iov_len = sizeof("name"); jiov[3].iov_base = namebuf; jiov[3].iov_len = sizeof(namebuf); *(const void **)&jiov[4].iov_base = "errmsg"; jiov[4].iov_len = sizeof("errmsg"); jiov[5].iov_base = jail_errmsg; jiov[5].iov_len = JAIL_ERRMSGLEN; jail_errmsg[0] = 0; jid = jail_get(jiov, 6, 0); if (jid < 0) { if (!jail_errmsg[0]) snprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno)); return NULL; } else { name = strdup(namebuf); if (name == NULL) strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN); } return name; } freebsd-libs-10.1~svn273304/lib/libjail/jail.h0000644000000000000000000000464611232615531015547 0ustar /*- * Copyright (c) 2009 James Gritton. * 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. * * $FreeBSD$ */ #ifndef _JAIL_H #define _JAIL_H #define JP_RAWVALUE 0x01 #define JP_BOOL 0x02 #define JP_NOBOOL 0x04 #define JP_JAILSYS 0x08 #define JAIL_ERRMSGLEN 1024 extern char jail_errmsg[]; struct jailparam { char *jp_name; void *jp_value; size_t jp_valuelen; size_t jp_elemlen; int jp_ctltype; int jp_structtype; unsigned jp_flags; }; __BEGIN_DECLS extern int jail_getid(const char *name); extern char *jail_getname(int jid); extern int jail_setv(int flags, ...); extern int jail_getv(int flags, ...); extern int jailparam_all(struct jailparam **jpp); extern int jailparam_init(struct jailparam *jp, const char *name); extern int jailparam_import(struct jailparam *jp, const char *value); extern int jailparam_import_raw(struct jailparam *jp, void *value, size_t valuelen); extern int jailparam_set(struct jailparam *jp, unsigned njp, int flags); extern int jailparam_get(struct jailparam *jp, unsigned njp, int flags); extern char *jailparam_export(struct jailparam *jp); extern void jailparam_free(struct jailparam *jp, unsigned njp); __END_DECLS #endif /* _JAIL_H */ freebsd-libs-10.1~svn273304/lib/libmemstat/0000755000000000000000000000000012421417266015206 5ustar freebsd-libs-10.1~svn273304/lib/libmemstat/memstat.c0000644000000000000000000002136211615472507017033 0ustar /*- * Copyright (c) 2005 Robert N. M. Watson * 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. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include "memstat.h" #include "memstat_internal.h" const char * memstat_strerror(int error) { switch (error) { case MEMSTAT_ERROR_NOMEMORY: return ("Cannot allocate memory"); case MEMSTAT_ERROR_VERSION: return ("Version mismatch"); case MEMSTAT_ERROR_PERMISSION: return ("Permission denied"); case MEMSTAT_ERROR_DATAERROR: return ("Data format error"); case MEMSTAT_ERROR_KVM: return ("KVM error"); case MEMSTAT_ERROR_KVM_NOSYMBOL: return ("KVM unable to find symbol"); case MEMSTAT_ERROR_KVM_SHORTREAD: return ("KVM short read"); case MEMSTAT_ERROR_UNDEFINED: default: return ("Unknown error"); } } struct memory_type_list * memstat_mtl_alloc(void) { struct memory_type_list *mtlp; mtlp = malloc(sizeof(*mtlp)); if (mtlp == NULL) return (NULL); LIST_INIT(&mtlp->mtl_list); mtlp->mtl_error = MEMSTAT_ERROR_UNDEFINED; return (mtlp); } struct memory_type * memstat_mtl_first(struct memory_type_list *list) { return (LIST_FIRST(&list->mtl_list)); } struct memory_type * memstat_mtl_next(struct memory_type *mtp) { return (LIST_NEXT(mtp, mt_list)); } void _memstat_mtl_empty(struct memory_type_list *list) { struct memory_type *mtp; while ((mtp = LIST_FIRST(&list->mtl_list))) { free(mtp->mt_percpu_alloc); free(mtp->mt_percpu_cache); LIST_REMOVE(mtp, mt_list); free(mtp); } } void memstat_mtl_free(struct memory_type_list *list) { _memstat_mtl_empty(list); free(list); } int memstat_mtl_geterror(struct memory_type_list *list) { return (list->mtl_error); } /* * Look for an existing memory_type entry in a memory_type list, based on the * allocator and name of the type. If not found, return NULL. No errno or * memstat error. */ struct memory_type * memstat_mtl_find(struct memory_type_list *list, int allocator, const char *name) { struct memory_type *mtp; LIST_FOREACH(mtp, &list->mtl_list, mt_list) { if ((mtp->mt_allocator == allocator || allocator == ALLOCATOR_ANY) && strcmp(mtp->mt_name, name) == 0) return (mtp); } return (NULL); } /* * Allocate a new memory_type with the specificed allocator type and name, * then insert into the list. The structure will be zero'd. * * libmemstat(3) internal function. */ struct memory_type * _memstat_mt_allocate(struct memory_type_list *list, int allocator, const char *name, int maxcpus) { struct memory_type *mtp; mtp = malloc(sizeof(*mtp)); if (mtp == NULL) return (NULL); bzero(mtp, sizeof(*mtp)); mtp->mt_allocator = allocator; mtp->mt_percpu_alloc = malloc(sizeof(struct mt_percpu_alloc_s) * maxcpus); mtp->mt_percpu_cache = malloc(sizeof(struct mt_percpu_cache_s) * maxcpus); strlcpy(mtp->mt_name, name, MEMTYPE_MAXNAME); LIST_INSERT_HEAD(&list->mtl_list, mtp, mt_list); return (mtp); } /* * Reset any libmemstat(3)-owned statistics in a memory_type record so that * it can be reused without incremental addition problems. Caller-owned * memory is left "as-is", and must be updated by the caller if desired. * * libmemstat(3) internal function. */ void _memstat_mt_reset_stats(struct memory_type *mtp, int maxcpus) { int i; mtp->mt_countlimit = 0; mtp->mt_byteslimit = 0; mtp->mt_sizemask = 0; mtp->mt_size = 0; mtp->mt_memalloced = 0; mtp->mt_memfreed = 0; mtp->mt_numallocs = 0; mtp->mt_numfrees = 0; mtp->mt_bytes = 0; mtp->mt_count = 0; mtp->mt_free = 0; mtp->mt_failures = 0; mtp->mt_sleeps = 0; mtp->mt_zonefree = 0; mtp->mt_kegfree = 0; for (i = 0; i < maxcpus; i++) { mtp->mt_percpu_alloc[i].mtp_memalloced = 0; mtp->mt_percpu_alloc[i].mtp_memfreed = 0; mtp->mt_percpu_alloc[i].mtp_numallocs = 0; mtp->mt_percpu_alloc[i].mtp_numfrees = 0; mtp->mt_percpu_alloc[i].mtp_sizemask = 0; mtp->mt_percpu_cache[i].mtp_free = 0; } } /* * Accessor methods for struct memory_type. Avoids encoding the structure * ABI into the application. */ const char * memstat_get_name(const struct memory_type *mtp) { return (mtp->mt_name); } int memstat_get_allocator(const struct memory_type *mtp) { return (mtp->mt_allocator); } uint64_t memstat_get_countlimit(const struct memory_type *mtp) { return (mtp->mt_countlimit); } uint64_t memstat_get_byteslimit(const struct memory_type *mtp) { return (mtp->mt_byteslimit); } uint64_t memstat_get_sizemask(const struct memory_type *mtp) { return (mtp->mt_sizemask); } uint64_t memstat_get_size(const struct memory_type *mtp) { return (mtp->mt_size); } uint64_t memstat_get_memalloced(const struct memory_type *mtp) { return (mtp->mt_memalloced); } uint64_t memstat_get_memfreed(const struct memory_type *mtp) { return (mtp->mt_memfreed); } uint64_t memstat_get_numallocs(const struct memory_type *mtp) { return (mtp->mt_numallocs); } uint64_t memstat_get_numfrees(const struct memory_type *mtp) { return (mtp->mt_numfrees); } uint64_t memstat_get_bytes(const struct memory_type *mtp) { return (mtp->mt_bytes); } uint64_t memstat_get_count(const struct memory_type *mtp) { return (mtp->mt_count); } uint64_t memstat_get_free(const struct memory_type *mtp) { return (mtp->mt_free); } uint64_t memstat_get_failures(const struct memory_type *mtp) { return (mtp->mt_failures); } uint64_t memstat_get_sleeps(const struct memory_type *mtp) { return (mtp->mt_sleeps); } void * memstat_get_caller_pointer(const struct memory_type *mtp, int index) { return (mtp->mt_caller_pointer[index]); } void memstat_set_caller_pointer(struct memory_type *mtp, int index, void *value) { mtp->mt_caller_pointer[index] = value; } uint64_t memstat_get_caller_uint64(const struct memory_type *mtp, int index) { return (mtp->mt_caller_uint64[index]); } void memstat_set_caller_uint64(struct memory_type *mtp, int index, uint64_t value) { mtp->mt_caller_uint64[index] = value; } uint64_t memstat_get_zonefree(const struct memory_type *mtp) { return (mtp->mt_zonefree); } uint64_t memstat_get_kegfree(const struct memory_type *mtp) { return (mtp->mt_kegfree); } uint64_t memstat_get_percpu_memalloced(const struct memory_type *mtp, int cpu) { return (mtp->mt_percpu_alloc[cpu].mtp_memalloced); } uint64_t memstat_get_percpu_memfreed(const struct memory_type *mtp, int cpu) { return (mtp->mt_percpu_alloc[cpu].mtp_memfreed); } uint64_t memstat_get_percpu_numallocs(const struct memory_type *mtp, int cpu) { return (mtp->mt_percpu_alloc[cpu].mtp_numallocs); } uint64_t memstat_get_percpu_numfrees(const struct memory_type *mtp, int cpu) { return (mtp->mt_percpu_alloc[cpu].mtp_numfrees); } uint64_t memstat_get_percpu_sizemask(const struct memory_type *mtp, int cpu) { return (mtp->mt_percpu_alloc[cpu].mtp_sizemask); } void * memstat_get_percpu_caller_pointer(const struct memory_type *mtp, int cpu, int index) { return (mtp->mt_percpu_alloc[cpu].mtp_caller_pointer[index]); } void memstat_set_percpu_caller_pointer(struct memory_type *mtp, int cpu, int index, void *value) { mtp->mt_percpu_alloc[cpu].mtp_caller_pointer[index] = value; } uint64_t memstat_get_percpu_caller_uint64(const struct memory_type *mtp, int cpu, int index) { return (mtp->mt_percpu_alloc[cpu].mtp_caller_uint64[index]); } void memstat_set_percpu_caller_uint64(struct memory_type *mtp, int cpu, int index, uint64_t value) { mtp->mt_percpu_alloc[cpu].mtp_caller_uint64[index] = value; } uint64_t memstat_get_percpu_free(const struct memory_type *mtp, int cpu) { return (mtp->mt_percpu_cache[cpu].mtp_free); } freebsd-libs-10.1~svn273304/lib/libmemstat/libmemstat.30000644000000000000000000004207211722170275017437 0ustar .\" Copyright (c) 2005 Robert N. M. Watson .\" 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 AUTHORS 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 AUTHORS 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. .\" .\" $FreeBSD$ .\" .Dd February 25, 2012 .Dt LIBMEMSTAT 3 .Os .Sh NAME .Nm libmemstat .Nd "library interface to retrieve kernel memory allocator statistics" .Sh LIBRARY .Lb libmemstat .Sh SYNOPSIS .In sys/types.h .In memstat.h .Ss General Functions .Ft "const char *" .Fn memstat_strerror "int error" .Ss Memory Type List Management Functions .Ft "struct memory_type_list *" .Fn memstat_mtl_alloc "void" .Ft "struct memory_type *" .Fn memstat_mtl_first "struct memory_type_list *list" .Ft "struct memory_type *" .Fn memstat_mtl_next "struct memory_type *mtp" .Ft "struct memory_type *" .Fo memstat_mtl_find .Fa "struct memory_type_list *list" "int allocator" "const char *name" .Fc .Ft void .Fn memstat_mtl_free "struct memory_type_list *list" .Ft int .Fn memstat_mtl_geterror "struct memory_type_list *list" .Ss Allocator Query Functions .Ft int .Fn memstat_kvm_all "struct memory_type_list *list" "void *kvm_handle" .Ft int .Fn memstat_kvm_malloc "struct memory_type_list *list" "void *kvm_handle" .Ft int .Fn memstat_kvm_uma "struct memory_type_list *list" "void *kvm_handle" .Ft int .Fn memstat_sysctl_all "struct memory_type_list *list" "int flags" .Ft int .Fn memstat_sysctl_malloc "struct memory_type_list *list" "int flags" .Ft int .Fn memstat_sysctl_uma "struct memory_type_list *list" "int flags" .Ss Memory Type Accessor Methods .Ft "const char *" .Fn memstat_get_name "const struct memory_type *mtp" .Ft int .Fn memstat_get_allocator "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_countlimit "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_byteslimit "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_sizemask "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_size "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_memalloced "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_memfreed "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_numallocs "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_numfrees "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_bytes "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_count "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_free "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_failures "const struct memory_type *mtp" .Ft "void *" .Fn memstat_get_caller_pointer "const struct memory_type *mtp" "int index" .Ft void .Fo memstat_set_caller_pointer .Fa "struct memory_type *mtp" "int index" "void *value" .Fc .Ft uint64_t .Fn memstat_get_caller_uint64 "const struct memory_type *mtp" "int index" .Ft void .Fo memstat_set_caller_uint64 .Fa "struct memory_type *mtp" "int index" "uint64_t value" .Fc .Ft uint64_t .Fn memstat_get_zonefree "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_kegfree "const struct memory_type *mtp" .Ft uint64_t .Fn memstat_get_percpu_memalloced "const struct memory_type *mtp" "int cpu" .Ft uint64_t .Fn memstat_get_percpu_memfreed "const struct memory_type *mtp" "int cpu" .Ft uint64_t .Fn memstat_get_percpu_numallocs "const struct memory_type *mtp" "int cpu" .Ft uint64_t .Fn memstat_get_percpu_numfrees "const struct memory_type *mtp" "int cpu" .Ft uint64_t .Fn memstat_get_percpu_sizemask "const struct memory_type *mtp" "int cpu" .Ft "void *" .Fo memstat_get_percpu_caller_pointer .Fa "const struct memory_type *mtp" "int cpu" "int index" .Fc .Ft void .Fo memstat_set_percpu_caller_pointer .Fa "struct memory_type *mtp" "int cpu" "int index" "void *value" .Fc .Ft uint64_t .Fo memstat_get_percpu_caller_uint64 .Fa "const struct memory_type *mtp" "int cpu" "int index" .Fc .Ft void .Fo memstat_set_percpu_caller_uint64 .Fa "struct memory_type *mtp" "int cpu" "int index" "uint64_t value" .Fc .Ft uint64_t .Fn memstat_get_percpu_free "const struct memory_type *mtp" "int cpu" .Sh DESCRIPTION .Nm provides an interface to retrieve kernel memory allocator statistics, for the purposes of debugging and system monitoring, insulating applications from implementation details of the allocators, and allowing a tool to transparently support multiple allocators. .Nm supports both retrieving a single statistics snapshot, as well as incrementally updating statistics for long-term monitoring. .Pp .Nm describes each memory type using a .Vt "struct memory_type" , an opaque memory type accessed by the application using accessor functions in the library. .Nm returns and updates chains of .Vt "struct memory_type" via a .Vt "struct memory_type_list" , which will be allocated by calling .Fn memstat_mtl_alloc , and freed on completion using .Fn memstat_mtl_free . Lists of memory types are populated via calls that query the kernel for statistics information; currently: .Fn memstat_kvm_all , .Fn memstat_kvm_malloc , .Fn memstat_kvm_uma , .Fn memstat_sysctl_all , .Fn memstat_sysctl_uma , and .Fn memstat_sysctl_malloc . Repeated calls will incrementally update the list of memory types, permitting tracking over time without recreating all list state. If an error is detected during a query call, error condition information may be retrieved using .Fn memstat_mtl_geterror , and converted to a user-readable string using .Fn memstat_strerror . .Pp Freeing the list will free all memory type data in the list, and so invalidates any outstanding pointers to entries in the list. .Vt "struct memory_type" entries in the list may be iterated over using .Fn memstat_mtl_first and .Fn memstat_mtl_next , which respectively return the first entry in a list, and the next entry in a list. .Fn memstat_mtl_find , which will return a pointer to the first entry matching the passed parameters. .Pp A series of accessor methods is provided to access fields of the structure, including retrieving statistics and properties, as well as setting of caller owned fields. Direct application access to the data structure fields is not supported. .Ss Library Vt memory_type Ss Fields Each .Vt "struct memory_type" holds a description of the memory type, including its name and the allocator it is managed by, as well as current statistics on use. Some statistics are directly measured, others are derived from directly measured statistics. Certain high level statistics are present across all available allocators, such as the number of allocation and free operations; other measurements, such as the quantity of free items in per-CPU caches, or administrative limit on the number of allocations, is available only for specific allocators. .Ss Caller Vt memory_type Ss Fields .Vt "struct memory_type" includes fields to allow the application to store data, in the form of pointers and 64-bit integers, with memory types. For example, the application author might make use of one of the caller pointers to reference a more complex data structure tracking long-term behavior of the memory type, or a window system object that is used to render the state of the memory type. General and per-CPU storage is provided with each .Vt "struct memory_type" in the form of an array of pointers and integers. The array entries are accessed via the .Fa index argument to the get and set accessor methods. Possible values of .Fa index range between 0 and .Dv MEMSTAT_MAXCALLER . .Pp Caller-owned fields are initialized to 0 or .Dv NULL when a new .Vt "struct memory_type" is allocated and attached to a memory type list; these fields retain their values across queries that update library-owned fields. .Ss Allocator Types Currently, .Nm supports two kernel allocators: .Dv ALLOCATOR_UMA for .Xr uma 9 , and .Dv ALLOCATOR_MALLOC for .Xr malloc 9 . These values may be passed to .Fn memstat_mtl_find , and will be returned by .Fn memstat_get_allocator . Two additional constants in the allocator name space are defined: .Dv ALLOCATOR_UNKNOWN , which will only be returned as a result of a library error, and .Dv ALLOCATOR_ANY , which can be used to specify that returning types matching any allocator is permittable from .Fn memstat_mtl_find . .Ss Access Method List The following accessor methods are defined, of which some will be valid for a given memory type: .Bl -tag -width indent .It Fn memstat_get_name Return a pointer to the name of the memory type. Memory for the name is owned by .Nm and will be valid through a call to .Fn memstat_mtl_free . Note that names will be unique with respect to a single allocator, but that the same name might be used by different memory types owned by different memory allocators. .It Fn memstat_get_allocator Return an integer identifier for the memory allocator that owns the memory type. .It Fn memstat_get_countlimit If the memory type has an administrative limit on the number of simultaneous allocations, return it. .It Fn memstat_get_byteslimit If the memory type has an administrative limit on the number of bytes of memory that may be simultaneously allocated for the memory type, return it. .It Fn memstat_get_sizemask If the memory type supports variable allocation sizes, return a bitmask of sizes allocated for the memory type. .It Fn memstat_get_size If the memory type supports a fixed allocation size, return that size. .It Fn memstat_get_memalloced Return the total number of bytes allocated for the memory type over its lifetime. .It Fn memstat_get_memfreed Return the total number of bytes freed for the memory type over its lifetime. .It Fn memstat_get_numallocs Return the total number of allocations for the memory type over its lifetime. .It Fn memstat_get_numfrees Return the total number of frees for the memory type over its lifetime. .It Fn memstat_get_bytes Return the current number of bytes allocated to the memory type. .It Fn memstat_get_count Return the current number of allocations for the memory type. .It Fn memstat_get_free If the memory allocator supports a cache, return the number of items in the cache. .It Fn memstat_get_failures If the memory allocator and type permit allocation failures, return the number of allocation failures measured. .It Fn memstat_get_caller_pointer Return a caller-owned pointer for the memory type. .It Fn memstat_set_caller_pointer Set a caller-owned pointer for the memory type. .It Fn memstat_get_caller_uint64 Return a caller-owned integer for the memory type. .It Fn memstat_set_caller_uint64 Set a caller-owned integer for the memory type. .It Fn memstat_get_zonefree If the memory allocator supports a multi-level allocation structure, return the number of cached items in the zone. These items will be in a fully constructed state available for immediate use. .It Fn memstat_get_kegfree If the memory allocator supports a multi-level allocation structure, return the number of cached items in the keg. These items may be in a partially constructed state, and may require further processing before they can be made available for use. .It Fn memstat_get_percpu_memalloced If the memory allocator supports per-CPU statistics, return the number of bytes of memory allocated for the memory type on the CPU over its lifetime. .It Fn memstat_get_percpu_memfreed If the memory allocator supports per-CPU statistics, return the number of bytes of memory freed from the memory type on the CPU over its lifetime. .It Fn memstat_get_percpu_numallocs If the memory allocator supports per-CPU statistics, return the number of allocations for the memory type on the CPU over its lifetime. .It Fn memstat_get_percpu_numfrees If the memory allocator supports per-CPU statistics, return the number of frees for the memory type on the CPU over its lifetime. .It Fn memstat_get_percpu_sizemask If the memory allocator supports variable size memory allocation and per-CPU statistics, return the size bitmask for the memory type on the CPU. .It Fn memstat_get_percpu_caller_pointer Return a caller-owned per-CPU pointer for the memory type. .It Fn memstat_set_percpu_caller_pointer Set a caller-owned per-CPU pointer for the memory type. .It Fn memstat_get_percpu_caller_uint64 Return a caller-owned per-CPU integer for the memory type. .It Fn memstat_set_percpu_caller_uint64 Set a caller-owned per-CPU integer for the memory type. .It Fn memstat_get_percpu_free If the memory allocator supports a per-CPU cache, return the number of free items in the per-CPU cache of the designated CPU. .El .Sh RETURN VALUES .Nm functions fall into three categories: functions returning a pointer to an object, functions returning an integer return value, and functions implementing accessor methods returning data from a .Vt "struct memory_type" . .Pp Functions returning a pointer to an object will generally return .Dv NULL on failure. .Fn memstat_mtl_alloc will return an error value via .Va errno , which will consist of the value .Er ENOMEM . Functions .Fn memstat_mtl_first , .Fn memstat_mtl_next , and .Fn memstat_mtl_find will return .Dv NULL when there is no entry or match in the list; however, this is not considered a failure mode and no error value is available. .Pp Functions returning an integer success value will return 0 on success, or \-1 on failure. If a failure is returned, the list error access method, .Fn memstat_mtl_geterror , may be used to retrieve the error state. The string representation of the error may be retrieved using .Fn memstat_strerror . Possible error values are: .Bl -tag -width ".Dv MEMSTAT_ERROR_KVM_SHORTREAD" .It Dv MEMSTAT_ERROR_UNDEFINED Undefined error. Occurs if .Fn memstat_mtl_geterror is called on a list before an error associated with the list has occurred. .It Dv MEMSTAT_ERROR_NOMEMORY Insufficient memory. Occurs if library calls to .Xr malloc 3 fail, or if a system call to retrieve kernel statistics fails with .Er ENOMEM . .It Dv MEMSTAT_ERROR_VERSION Returned if the current version of .Nm is unable to interpret the statistics data returned by the kernel due to an explicit version mismatch, or to differences in data structures that cannot be reconciled. .It Dv MEMSTAT_ERROR_PERMISSION Returned if a statistics source returns .Va errno values of .Er EACCES or .Er EPERM . .It Dv MEMSTAT_ERROR_DATAERROR Returned if .Nm is unable to interpret statistics data returned by the data source, even though there does not appear to be a version problem. .It Dv MEMSTAT_ERROR_KVM Returned if .Nm experiences an error while using .Xr kvm 3 interfaces to query statistics data. Use .Xr kvm_geterr 3 to retrieve the error. .It Dv MEMSTAT_ERROR_KVM_NOSYMBOL Returned if .Nm is unable to read a required symbol from the kernel being operated on. .It Dv MEMSTAT_ERROR_KVM_SHORTREAD Returned if .Nm attempts to read data from a live memory image or kernel core dump and insufficient data is returned. .El .Pp Finally, functions returning data from a .Vt "struct memory_type" pointer are not permitted to fail, and directly return either a statistic or pointer to a string. .Sh EXAMPLES Create a memory type list, query the .Xr uma 9 memory allocator for available statistics, and print out the number of allocations performed by the .Dv mbuf zone. .Bd -literal -offset indent struct memory_type_list *mtlp; struct memory_type *mtp; uint64_t mbuf_count; mtlp = memstat_mtl_alloc(); if (mtlp == NULL) err(-1, "memstat_mtl_alloc"); if (memstat_sysctl_uma(mtlp, 0) < 0) err(-1, "memstat_sysctl_uma"); mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, "mbuf"); if (mtp == NULL) errx(-1, "memstat_mtl_find: mbuf not found"); mbuf_count = memstat_get_count(mtp); memstat_mtl_free(mtlp); printf("mbufs: %llu\en", (unsigned long long)mbuf_count); .Ed .Sh SEE ALSO .Xr malloc 9 , .Xr uma 9 .Sh HISTORY The .Nm library appeared in .Fx 6.0 . .Sh AUTHORS The kernel memory allocator changes necessary to support a general purpose monitoring library, along with the library, were written by .An Robert Watson Aq rwatson@FreeBSD.org . .Sh BUGS There are memory allocators in the kernel, such as the VM page allocator and .Nm sf_buf allocator, which are not currently supported by .Nm . .Pp Once a memory type is present on a memory type list, it will not be removed even if the kernel no longer presents information on the type via its monitoring interfaces. In order to flush removed memory types, it is necessary to free the entire list and allocate a new one. freebsd-libs-10.1~svn273304/lib/libmemstat/memstat_all.c0000644000000000000000000000365510275140373017662 0ustar /*- * Copyright (c) 2005 Robert N. M. Watson * 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. * * $FreeBSD$ */ #include #include #include "memstat.h" /* * Query all available memory allocator sources. Currently this consists of * malloc(9) and UMA(9). */ int memstat_sysctl_all(struct memory_type_list *mtlp, int flags) { if (memstat_sysctl_malloc(mtlp, flags) < 0) return (-1); if (memstat_sysctl_uma(mtlp, flags) < 0) return (-1); return (0); } int memstat_kvm_all(struct memory_type_list *mtlp, void *kvm_handle) { if (memstat_kvm_malloc(mtlp, kvm_handle) < 0) return (-1); if (memstat_kvm_uma(mtlp, kvm_handle) < 0) return (-1); return (0); } freebsd-libs-10.1~svn273304/lib/libmemstat/memstat_internal.h0000644000000000000000000001146011615472507020732 0ustar /*- * Copyright (c) 2005 Robert N. M. Watson * 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. * * $FreeBSD$ */ #ifndef _MEMSTAT_INTERNAL_H_ #define _MEMSTAT_INTERNAL_H_ /* * memstat maintains its own internal notion of statistics on each memory * type, common across UMA and kernel malloc. Some fields are straight from * the allocator statistics, others are derived when extracted from the * kernel. A struct memory_type will describe each type supported by an * allocator. memory_type structures can be chained into lists. */ struct memory_type { /* * Static properties of type. */ int mt_allocator; /* malloc(9), uma(9), etc. */ char mt_name[MEMTYPE_MAXNAME]; /* name of memory type. */ /* * (Relatively) static zone settings, that don't uniquely identify * the zone, but also don't change much. */ uint64_t mt_countlimit; /* 0, or maximum allocations. */ uint64_t mt_byteslimit; /* 0, or maximum bytes. */ uint64_t mt_sizemask; /* malloc: allocated size bitmask. */ uint64_t mt_size; /* uma: size of objects. */ /* * Zone or type information that includes all caches and any central * zone state. Depending on the allocator, this may be synthesized * from several sources, or directly measured. */ uint64_t mt_memalloced; /* Bytes allocated over life time. */ uint64_t mt_memfreed; /* Bytes freed over life time. */ uint64_t mt_numallocs; /* Allocations over life time. */ uint64_t mt_numfrees; /* Frees over life time. */ uint64_t mt_bytes; /* Bytes currently allocated. */ uint64_t mt_count; /* Number of current allocations. */ uint64_t mt_free; /* Number of cached free items. */ uint64_t mt_failures; /* Number of allocation failures. */ uint64_t mt_sleeps; /* Number of allocation sleeps. */ /* * Caller-owned memory. */ void *mt_caller_pointer[MEMSTAT_MAXCALLER]; /* Pointers. */ uint64_t mt_caller_uint64[MEMSTAT_MAXCALLER]; /* Integers. */ /* * For allocators making use of per-CPU caches, we also provide raw * statistics from the central allocator and each per-CPU cache, * which (combined) sometimes make up the above general statistics. * * First, central zone/type state, all numbers excluding any items * cached in per-CPU caches. * * XXXRW: Might be desirable to separately expose allocation stats * from zone, which should (combined with per-cpu) add up to the * global stats above. */ uint64_t mt_zonefree; /* Free items in zone. */ uint64_t mt_kegfree; /* Free items in keg. */ /* * Per-CPU measurements fall into two categories: per-CPU allocation, * and per-CPU cache state. */ struct mt_percpu_alloc_s { uint64_t mtp_memalloced;/* Per-CPU mt_memalloced. */ uint64_t mtp_memfreed; /* Per-CPU mt_memfreed. */ uint64_t mtp_numallocs; /* Per-CPU mt_numallocs. */ uint64_t mtp_numfrees; /* Per-CPU mt_numfrees. */ uint64_t mtp_sizemask; /* Per-CPU mt_sizemask. */ void *mtp_caller_pointer[MEMSTAT_MAXCALLER]; uint64_t mtp_caller_uint64[MEMSTAT_MAXCALLER]; } *mt_percpu_alloc; struct mt_percpu_cache_s { uint64_t mtp_free; /* Per-CPU cache free items. */ } *mt_percpu_cache; LIST_ENTRY(memory_type) mt_list; /* List of types. */ }; /* * Description of struct memory_type_list is in memstat.h. */ struct memory_type_list { LIST_HEAD(, memory_type) mtl_list; int mtl_error; }; void _memstat_mtl_empty(struct memory_type_list *list); struct memory_type *_memstat_mt_allocate(struct memory_type_list *list, int allocator, const char *name, int maxcpus); void _memstat_mt_reset_stats(struct memory_type *mtp, int maxcpus); #endif /* !_MEMSTAT_INTERNAL_H_ */ freebsd-libs-10.1~svn273304/lib/libmemstat/memstat_malloc.c0000644000000000000000000002504511615472507020364 0ustar /*- * Copyright (c) 2005 Robert N. M. Watson * 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. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include #include "memstat.h" #include "memstat_internal.h" static struct nlist namelist[] = { #define X_KMEMSTATISTICS 0 { .n_name = "_kmemstatistics" }, #define X_MP_MAXCPUS 1 { .n_name = "_mp_maxcpus" }, { .n_name = "" }, }; /* * Extract malloc(9) statistics from the running kernel, and store all memory * type information in the passed list. For each type, check the list for an * existing entry with the right name/allocator -- if present, update that * entry. Otherwise, add a new entry. On error, the entire list will be * cleared, as entries will be in an inconsistent state. * * To reduce the level of work for a list that starts empty, we keep around a * hint as to whether it was empty when we began, so we can avoid searching * the list for entries to update. Updates are O(n^2) due to searching for * each entry before adding it. */ int memstat_sysctl_malloc(struct memory_type_list *list, int flags) { struct malloc_type_stream_header *mtshp; struct malloc_type_header *mthp; struct malloc_type_stats *mtsp; struct memory_type *mtp; int count, hint_dontsearch, i, j, maxcpus; char *buffer, *p; size_t size; hint_dontsearch = LIST_EMPTY(&list->mtl_list); /* * Query the number of CPUs, number of malloc types so that we can * guess an initial buffer size. We loop until we succeed or really * fail. Note that the value of maxcpus we query using sysctl is not * the version we use when processing the real data -- that is read * from the header. */ retry: size = sizeof(maxcpus); if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) { if (errno == EACCES || errno == EPERM) list->mtl_error = MEMSTAT_ERROR_PERMISSION; else list->mtl_error = MEMSTAT_ERROR_DATAERROR; return (-1); } if (size != sizeof(maxcpus)) { list->mtl_error = MEMSTAT_ERROR_DATAERROR; return (-1); } size = sizeof(count); if (sysctlbyname("kern.malloc_count", &count, &size, NULL, 0) < 0) { if (errno == EACCES || errno == EPERM) list->mtl_error = MEMSTAT_ERROR_PERMISSION; else list->mtl_error = MEMSTAT_ERROR_VERSION; return (-1); } if (size != sizeof(count)) { list->mtl_error = MEMSTAT_ERROR_DATAERROR; return (-1); } size = sizeof(*mthp) + count * (sizeof(*mthp) + sizeof(*mtsp) * maxcpus); buffer = malloc(size); if (buffer == NULL) { list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } if (sysctlbyname("kern.malloc_stats", buffer, &size, NULL, 0) < 0) { /* * XXXRW: ENOMEM is an ambiguous return, we should bound the * number of loops, perhaps. */ if (errno == ENOMEM) { free(buffer); goto retry; } if (errno == EACCES || errno == EPERM) list->mtl_error = MEMSTAT_ERROR_PERMISSION; else list->mtl_error = MEMSTAT_ERROR_VERSION; free(buffer); return (-1); } if (size == 0) { free(buffer); return (0); } if (size < sizeof(*mtshp)) { list->mtl_error = MEMSTAT_ERROR_VERSION; free(buffer); return (-1); } p = buffer; mtshp = (struct malloc_type_stream_header *)p; p += sizeof(*mtshp); if (mtshp->mtsh_version != MALLOC_TYPE_STREAM_VERSION) { list->mtl_error = MEMSTAT_ERROR_VERSION; free(buffer); return (-1); } /* * For the remainder of this function, we are quite trusting about * the layout of structures and sizes, since we've determined we have * a matching version and acceptable CPU count. */ maxcpus = mtshp->mtsh_maxcpus; count = mtshp->mtsh_count; for (i = 0; i < count; i++) { mthp = (struct malloc_type_header *)p; p += sizeof(*mthp); if (hint_dontsearch == 0) { mtp = memstat_mtl_find(list, ALLOCATOR_MALLOC, mthp->mth_name); } else mtp = NULL; if (mtp == NULL) mtp = _memstat_mt_allocate(list, ALLOCATOR_MALLOC, mthp->mth_name, maxcpus); if (mtp == NULL) { _memstat_mtl_empty(list); free(buffer); list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } /* * Reset the statistics on a current node. */ _memstat_mt_reset_stats(mtp, maxcpus); for (j = 0; j < maxcpus; j++) { mtsp = (struct malloc_type_stats *)p; p += sizeof(*mtsp); /* * Sumarize raw statistics across CPUs into coalesced * statistics. */ mtp->mt_memalloced += mtsp->mts_memalloced; mtp->mt_memfreed += mtsp->mts_memfreed; mtp->mt_numallocs += mtsp->mts_numallocs; mtp->mt_numfrees += mtsp->mts_numfrees; mtp->mt_sizemask |= mtsp->mts_size; /* * Copies of per-CPU statistics. */ mtp->mt_percpu_alloc[j].mtp_memalloced = mtsp->mts_memalloced; mtp->mt_percpu_alloc[j].mtp_memfreed = mtsp->mts_memfreed; mtp->mt_percpu_alloc[j].mtp_numallocs = mtsp->mts_numallocs; mtp->mt_percpu_alloc[j].mtp_numfrees = mtsp->mts_numfrees; mtp->mt_percpu_alloc[j].mtp_sizemask = mtsp->mts_size; } /* * Derived cross-CPU statistics. */ mtp->mt_bytes = mtp->mt_memalloced - mtp->mt_memfreed; mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees; } free(buffer); return (0); } static int kread(kvm_t *kvm, void *kvm_pointer, void *address, size_t size, size_t offset) { ssize_t ret; ret = kvm_read(kvm, (unsigned long)kvm_pointer + offset, address, size); if (ret < 0) return (MEMSTAT_ERROR_KVM); if ((size_t)ret != size) return (MEMSTAT_ERROR_KVM_SHORTREAD); return (0); } static int kread_string(kvm_t *kvm, const void *kvm_pointer, char *buffer, int buflen) { ssize_t ret; int i; for (i = 0; i < buflen; i++) { ret = kvm_read(kvm, __DECONST(unsigned long, kvm_pointer) + i, &(buffer[i]), sizeof(char)); if (ret < 0) return (MEMSTAT_ERROR_KVM); if ((size_t)ret != sizeof(char)) return (MEMSTAT_ERROR_KVM_SHORTREAD); if (buffer[i] == '\0') return (0); } /* Truncate. */ buffer[i-1] = '\0'; return (0); } static int kread_symbol(kvm_t *kvm, int index, void *address, size_t size, size_t offset) { ssize_t ret; ret = kvm_read(kvm, namelist[index].n_value + offset, address, size); if (ret < 0) return (MEMSTAT_ERROR_KVM); if ((size_t)ret != size) return (MEMSTAT_ERROR_KVM_SHORTREAD); return (0); } int memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle) { struct memory_type *mtp; void *kmemstatistics; int hint_dontsearch, j, mp_maxcpus, ret; char name[MEMTYPE_MAXNAME]; struct malloc_type_stats *mts, *mtsp; struct malloc_type_internal *mtip; struct malloc_type type, *typep; kvm_t *kvm; kvm = (kvm_t *)kvm_handle; hint_dontsearch = LIST_EMPTY(&list->mtl_list); if (kvm_nlist(kvm, namelist) != 0) { list->mtl_error = MEMSTAT_ERROR_KVM; return (-1); } if (namelist[X_KMEMSTATISTICS].n_type == 0 || namelist[X_KMEMSTATISTICS].n_value == 0) { list->mtl_error = MEMSTAT_ERROR_KVM_NOSYMBOL; return (-1); } ret = kread_symbol(kvm, X_MP_MAXCPUS, &mp_maxcpus, sizeof(mp_maxcpus), 0); if (ret != 0) { list->mtl_error = ret; return (-1); } ret = kread_symbol(kvm, X_KMEMSTATISTICS, &kmemstatistics, sizeof(kmemstatistics), 0); if (ret != 0) { list->mtl_error = ret; return (-1); } mts = malloc(sizeof(struct malloc_type_stats) * mp_maxcpus); if (mts == NULL) { list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } for (typep = kmemstatistics; typep != NULL; typep = type.ks_next) { ret = kread(kvm, typep, &type, sizeof(type), 0); if (ret != 0) { _memstat_mtl_empty(list); free(mts); list->mtl_error = ret; return (-1); } ret = kread_string(kvm, (void *)type.ks_shortdesc, name, MEMTYPE_MAXNAME); if (ret != 0) { _memstat_mtl_empty(list); free(mts); list->mtl_error = ret; return (-1); } /* * Since our compile-time value for MAXCPU may differ from the * kernel's, we populate our own array. */ mtip = type.ks_handle; ret = kread(kvm, mtip->mti_stats, mts, mp_maxcpus * sizeof(struct malloc_type_stats), 0); if (ret != 0) { _memstat_mtl_empty(list); free(mts); list->mtl_error = ret; return (-1); } if (hint_dontsearch == 0) { mtp = memstat_mtl_find(list, ALLOCATOR_MALLOC, name); } else mtp = NULL; if (mtp == NULL) mtp = _memstat_mt_allocate(list, ALLOCATOR_MALLOC, name, mp_maxcpus); if (mtp == NULL) { _memstat_mtl_empty(list); free(mts); list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } /* * This logic is replicated from kern_malloc.c, and should * be kept in sync. */ _memstat_mt_reset_stats(mtp, mp_maxcpus); for (j = 0; j < mp_maxcpus; j++) { mtsp = &mts[j]; mtp->mt_memalloced += mtsp->mts_memalloced; mtp->mt_memfreed += mtsp->mts_memfreed; mtp->mt_numallocs += mtsp->mts_numallocs; mtp->mt_numfrees += mtsp->mts_numfrees; mtp->mt_sizemask |= mtsp->mts_size; mtp->mt_percpu_alloc[j].mtp_memalloced = mtsp->mts_memalloced; mtp->mt_percpu_alloc[j].mtp_memfreed = mtsp->mts_memfreed; mtp->mt_percpu_alloc[j].mtp_numallocs = mtsp->mts_numallocs; mtp->mt_percpu_alloc[j].mtp_numfrees = mtsp->mts_numfrees; mtp->mt_percpu_alloc[j].mtp_sizemask = mtsp->mts_size; } mtp->mt_bytes = mtp->mt_memalloced - mtp->mt_memfreed; mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees; } return (0); } freebsd-libs-10.1~svn273304/lib/libmemstat/Makefile0000644000000000000000000000141511230653404016640 0ustar # $FreeBSD$ WARNS?= 3 LIB= memstat SHLIB_MAJOR= 3 DPADD= ${LIBKVM} LDADD= -lkvm SRCS+= memstat.c SRCS+= memstat_all.c SRCS+= memstat_malloc.c SRCS+= memstat_uma.c INCS= memstat.h MAN= libmemstat.3 MLINKS+= libmemstat.3 memstat_mtl_alloc.3 MLINKS+= libmemstat.3 memstat_mtl_first.3 MLINKS+= libmemstat.3 memstat_mtl_next.3 MLINKS+= libmemstat.3 memstat_mtl_find.3 MLINKS+= libmemstat.3 memstat_mtl_free.3 MLINKS+= libmemstat.3 memstat_mtl_geterror.3 MLINKS+= libmemstat.3 memstat_strerror.3 MLINKS+= libmemstat.3 memstat_sysctl_all.3 MLINKS+= libmemstat.3 memstat_sysctl_malloc.3 MLINKS+= libmemstat.3 memstat_sysctl_uma.3 MLINKS+= libmemstat.3 memstat_kvm_all.3 MLINKS+= libmemstat.3 memstat_kvm_malloc.3 MLINKS+= libmemstat.3 memstat_kvm_uma.3 .include freebsd-libs-10.1~svn273304/lib/libmemstat/memstat.h0000644000000000000000000001562611615472507017046 0ustar /*- * Copyright (c) 2005 Robert N. M. Watson * 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. * * $FreeBSD$ */ #ifndef _MEMSTAT_H_ #define _MEMSTAT_H_ /* * Amount of caller data to maintain for each caller data slot. Applications * must not request more than this number of caller save data, or risk * corrupting internal libmemstat(3) data structures. A compile time check * in the application is probably appropriate. */ #define MEMSTAT_MAXCALLER 16 /* * libmemstat(3) is able to extract memory data from different allocators; * when it does so, it tags which allocator it got the data from so that * consumers can determine which fields are usable, as data returned varies * some. */ #define ALLOCATOR_UNKNOWN 0 #define ALLOCATOR_MALLOC 1 #define ALLOCATOR_UMA 2 #define ALLOCATOR_ANY 255 /* * Library maximum type name. Should be max(set of name maximums over * various allocators). */ #define MEMTYPE_MAXNAME 32 /* * Library error conditions, mostly from the underlying data sources. On * failure, functions typically return (-1) or (NULL); on success, (0) or a * valid data pointer. The error from the last operation is stored in * struct memory_type_list, and accessed via memstat_get_error(list). */ #define MEMSTAT_ERROR_UNDEFINED 0 /* Initialization value. */ #define MEMSTAT_ERROR_NOMEMORY 1 /* Out of memory. */ #define MEMSTAT_ERROR_VERSION 2 /* Unsupported version. */ #define MEMSTAT_ERROR_PERMISSION 3 /* Permission denied. */ #define MEMSTAT_ERROR_DATAERROR 5 /* Error in stat data. */ #define MEMSTAT_ERROR_KVM 6 /* See kvm_geterr() for err. */ #define MEMSTAT_ERROR_KVM_NOSYMBOL 7 /* Symbol not available. */ #define MEMSTAT_ERROR_KVM_SHORTREAD 8 /* Short kvm_read return. */ /* * Forward declare struct memory_type, which holds per-type properties and * statistics. This is an opaque type, to be frobbed only from within the * library, in order to avoid building ABI assumptions into the application. * Accessor methods should be used to get and sometimes set the fields from * consumers of the library. */ struct memory_type; /* * struct memory_type_list is the head of a list of memory types and * statistics. */ struct memory_type_list; __BEGIN_DECLS /* * Functions that operate without memory type or memory type list context. */ const char *memstat_strerror(int error); /* * Functions for managing memory type and statistics data. */ struct memory_type_list *memstat_mtl_alloc(void); struct memory_type *memstat_mtl_first(struct memory_type_list *list); struct memory_type *memstat_mtl_next(struct memory_type *mtp); struct memory_type *memstat_mtl_find(struct memory_type_list *list, int allocator, const char *name); void memstat_mtl_free(struct memory_type_list *list); int memstat_mtl_geterror(struct memory_type_list *list); /* * Functions to retrieve data from a live kernel using sysctl. */ int memstat_sysctl_all(struct memory_type_list *list, int flags); int memstat_sysctl_malloc(struct memory_type_list *list, int flags); int memstat_sysctl_uma(struct memory_type_list *list, int flags); /* * Functions to retrieve data from a kernel core (or /dev/kmem). */ int memstat_kvm_all(struct memory_type_list *list, void *kvm_handle); int memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle); int memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle); /* * Accessor methods for struct memory_type. */ const char *memstat_get_name(const struct memory_type *mtp); int memstat_get_allocator(const struct memory_type *mtp); uint64_t memstat_get_countlimit(const struct memory_type *mtp); uint64_t memstat_get_byteslimit(const struct memory_type *mtp); uint64_t memstat_get_sizemask(const struct memory_type *mtp); uint64_t memstat_get_size(const struct memory_type *mtp); uint64_t memstat_get_memalloced(const struct memory_type *mtp); uint64_t memstat_get_memfreed(const struct memory_type *mtp); uint64_t memstat_get_numallocs(const struct memory_type *mtp); uint64_t memstat_get_numfrees(const struct memory_type *mtp); uint64_t memstat_get_bytes(const struct memory_type *mtp); uint64_t memstat_get_count(const struct memory_type *mtp); uint64_t memstat_get_free(const struct memory_type *mtp); uint64_t memstat_get_failures(const struct memory_type *mtp); uint64_t memstat_get_sleeps(const struct memory_type *mtp); void *memstat_get_caller_pointer(const struct memory_type *mtp, int index); void memstat_set_caller_pointer(struct memory_type *mtp, int index, void *value); uint64_t memstat_get_caller_uint64(const struct memory_type *mtp, int index); void memstat_set_caller_uint64(struct memory_type *mtp, int index, uint64_t value); uint64_t memstat_get_zonefree(const struct memory_type *mtp); uint64_t memstat_get_kegfree(const struct memory_type *mtp); uint64_t memstat_get_percpu_memalloced(const struct memory_type *mtp, int cpu); uint64_t memstat_get_percpu_memfreed(const struct memory_type *mtp, int cpu); uint64_t memstat_get_percpu_numallocs(const struct memory_type *mtp, int cpu); uint64_t memstat_get_percpu_numfrees(const struct memory_type *mtp, int cpu); uint64_t memstat_get_percpu_sizemask(const struct memory_type *mtp, int cpu); void *memstat_get_percpu_caller_pointer( const struct memory_type *mtp, int cpu, int index); void memstat_set_percpu_caller_pointer(struct memory_type *mtp, int cpu, int index, void *value); uint64_t memstat_get_percpu_caller_uint64( const struct memory_type *mtp, int cpu, int index); void memstat_set_percpu_caller_uint64(struct memory_type *mtp, int cpu, int index, uint64_t value); uint64_t memstat_get_percpu_free(const struct memory_type *mtp, int cpu); __END_DECLS #endif /* !_MEMSTAT_H_ */ freebsd-libs-10.1~svn273304/lib/libmemstat/memstat_uma.c0000644000000000000000000003103712157763414017677 0ustar /*- * Copyright (c) 2005-2006 Robert N. M. Watson * 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. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "memstat.h" #include "memstat_internal.h" static struct nlist namelist[] = { #define X_UMA_KEGS 0 { .n_name = "_uma_kegs" }, #define X_MP_MAXID 1 { .n_name = "_mp_maxid" }, #define X_ALL_CPUS 2 { .n_name = "_all_cpus" }, { .n_name = "" }, }; /* * Extract uma(9) statistics from the running kernel, and store all memory * type information in the passed list. For each type, check the list for an * existing entry with the right name/allocator -- if present, update that * entry. Otherwise, add a new entry. On error, the entire list will be * cleared, as entries will be in an inconsistent state. * * To reduce the level of work for a list that starts empty, we keep around a * hint as to whether it was empty when we began, so we can avoid searching * the list for entries to update. Updates are O(n^2) due to searching for * each entry before adding it. */ int memstat_sysctl_uma(struct memory_type_list *list, int flags) { struct uma_stream_header *ushp; struct uma_type_header *uthp; struct uma_percpu_stat *upsp; struct memory_type *mtp; int count, hint_dontsearch, i, j, maxcpus, maxid; char *buffer, *p; size_t size; hint_dontsearch = LIST_EMPTY(&list->mtl_list); /* * Query the number of CPUs, number of malloc types so that we can * guess an initial buffer size. We loop until we succeed or really * fail. Note that the value of maxcpus we query using sysctl is not * the version we use when processing the real data -- that is read * from the header. */ retry: size = sizeof(maxid); if (sysctlbyname("kern.smp.maxid", &maxid, &size, NULL, 0) < 0) { if (errno == EACCES || errno == EPERM) list->mtl_error = MEMSTAT_ERROR_PERMISSION; else list->mtl_error = MEMSTAT_ERROR_DATAERROR; return (-1); } if (size != sizeof(maxid)) { list->mtl_error = MEMSTAT_ERROR_DATAERROR; return (-1); } size = sizeof(count); if (sysctlbyname("vm.zone_count", &count, &size, NULL, 0) < 0) { if (errno == EACCES || errno == EPERM) list->mtl_error = MEMSTAT_ERROR_PERMISSION; else list->mtl_error = MEMSTAT_ERROR_VERSION; return (-1); } if (size != sizeof(count)) { list->mtl_error = MEMSTAT_ERROR_DATAERROR; return (-1); } size = sizeof(*uthp) + count * (sizeof(*uthp) + sizeof(*upsp) * (maxid + 1)); buffer = malloc(size); if (buffer == NULL) { list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } if (sysctlbyname("vm.zone_stats", buffer, &size, NULL, 0) < 0) { /* * XXXRW: ENOMEM is an ambiguous return, we should bound the * number of loops, perhaps. */ if (errno == ENOMEM) { free(buffer); goto retry; } if (errno == EACCES || errno == EPERM) list->mtl_error = MEMSTAT_ERROR_PERMISSION; else list->mtl_error = MEMSTAT_ERROR_VERSION; free(buffer); return (-1); } if (size == 0) { free(buffer); return (0); } if (size < sizeof(*ushp)) { list->mtl_error = MEMSTAT_ERROR_VERSION; free(buffer); return (-1); } p = buffer; ushp = (struct uma_stream_header *)p; p += sizeof(*ushp); if (ushp->ush_version != UMA_STREAM_VERSION) { list->mtl_error = MEMSTAT_ERROR_VERSION; free(buffer); return (-1); } /* * For the remainder of this function, we are quite trusting about * the layout of structures and sizes, since we've determined we have * a matching version and acceptable CPU count. */ maxcpus = ushp->ush_maxcpus; count = ushp->ush_count; for (i = 0; i < count; i++) { uthp = (struct uma_type_header *)p; p += sizeof(*uthp); if (hint_dontsearch == 0) { mtp = memstat_mtl_find(list, ALLOCATOR_UMA, uthp->uth_name); } else mtp = NULL; if (mtp == NULL) mtp = _memstat_mt_allocate(list, ALLOCATOR_UMA, uthp->uth_name, maxid + 1); if (mtp == NULL) { _memstat_mtl_empty(list); free(buffer); list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } /* * Reset the statistics on a current node. */ _memstat_mt_reset_stats(mtp, maxid + 1); mtp->mt_numallocs = uthp->uth_allocs; mtp->mt_numfrees = uthp->uth_frees; mtp->mt_failures = uthp->uth_fails; mtp->mt_sleeps = uthp->uth_sleeps; for (j = 0; j < maxcpus; j++) { upsp = (struct uma_percpu_stat *)p; p += sizeof(*upsp); mtp->mt_percpu_cache[j].mtp_free = upsp->ups_cache_free; mtp->mt_free += upsp->ups_cache_free; mtp->mt_numallocs += upsp->ups_allocs; mtp->mt_numfrees += upsp->ups_frees; } mtp->mt_size = uthp->uth_size; mtp->mt_memalloced = mtp->mt_numallocs * uthp->uth_size; mtp->mt_memfreed = mtp->mt_numfrees * uthp->uth_size; mtp->mt_bytes = mtp->mt_memalloced - mtp->mt_memfreed; mtp->mt_countlimit = uthp->uth_limit; mtp->mt_byteslimit = uthp->uth_limit * uthp->uth_size; mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees; mtp->mt_zonefree = uthp->uth_zone_free; /* * UMA secondary zones share a keg with the primary zone. To * avoid double-reporting of free items, report keg free * items only in the primary zone. */ if (!(uthp->uth_zone_flags & UTH_ZONE_SECONDARY)) { mtp->mt_kegfree = uthp->uth_keg_free; mtp->mt_free += mtp->mt_kegfree; } mtp->mt_free += mtp->mt_zonefree; } free(buffer); return (0); } static int kread(kvm_t *kvm, void *kvm_pointer, void *address, size_t size, size_t offset) { ssize_t ret; ret = kvm_read(kvm, (unsigned long)kvm_pointer + offset, address, size); if (ret < 0) return (MEMSTAT_ERROR_KVM); if ((size_t)ret != size) return (MEMSTAT_ERROR_KVM_SHORTREAD); return (0); } static int kread_string(kvm_t *kvm, const void *kvm_pointer, char *buffer, int buflen) { ssize_t ret; int i; for (i = 0; i < buflen; i++) { ret = kvm_read(kvm, (unsigned long)kvm_pointer + i, &(buffer[i]), sizeof(char)); if (ret < 0) return (MEMSTAT_ERROR_KVM); if ((size_t)ret != sizeof(char)) return (MEMSTAT_ERROR_KVM_SHORTREAD); if (buffer[i] == '\0') return (0); } /* Truncate. */ buffer[i-1] = '\0'; return (0); } static int kread_symbol(kvm_t *kvm, int index, void *address, size_t size, size_t offset) { ssize_t ret; ret = kvm_read(kvm, namelist[index].n_value + offset, address, size); if (ret < 0) return (MEMSTAT_ERROR_KVM); if ((size_t)ret != size) return (MEMSTAT_ERROR_KVM_SHORTREAD); return (0); } /* * memstat_kvm_uma() is similar to memstat_sysctl_uma(), only it extracts * UMA(9) statistics from a kernel core/memory file. */ int memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle) { LIST_HEAD(, uma_keg) uma_kegs; struct memory_type *mtp; struct uma_bucket *ubp, ub; struct uma_cache *ucp, *ucp_array; struct uma_zone *uzp, uz; struct uma_keg *kzp, kz; int hint_dontsearch, i, mp_maxid, ret; char name[MEMTYPE_MAXNAME]; cpuset_t all_cpus; long cpusetsize; kvm_t *kvm; kvm = (kvm_t *)kvm_handle; hint_dontsearch = LIST_EMPTY(&list->mtl_list); if (kvm_nlist(kvm, namelist) != 0) { list->mtl_error = MEMSTAT_ERROR_KVM; return (-1); } if (namelist[X_UMA_KEGS].n_type == 0 || namelist[X_UMA_KEGS].n_value == 0) { list->mtl_error = MEMSTAT_ERROR_KVM_NOSYMBOL; return (-1); } ret = kread_symbol(kvm, X_MP_MAXID, &mp_maxid, sizeof(mp_maxid), 0); if (ret != 0) { list->mtl_error = ret; return (-1); } ret = kread_symbol(kvm, X_UMA_KEGS, &uma_kegs, sizeof(uma_kegs), 0); if (ret != 0) { list->mtl_error = ret; return (-1); } cpusetsize = sysconf(_SC_CPUSET_SIZE); if (cpusetsize == -1 || (u_long)cpusetsize > sizeof(cpuset_t)) { list->mtl_error = MEMSTAT_ERROR_KVM_NOSYMBOL; return (-1); } CPU_ZERO(&all_cpus); ret = kread_symbol(kvm, X_ALL_CPUS, &all_cpus, cpusetsize, 0); if (ret != 0) { list->mtl_error = ret; return (-1); } ucp_array = malloc(sizeof(struct uma_cache) * (mp_maxid + 1)); if (ucp_array == NULL) { list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } for (kzp = LIST_FIRST(&uma_kegs); kzp != NULL; kzp = LIST_NEXT(&kz, uk_link)) { ret = kread(kvm, kzp, &kz, sizeof(kz), 0); if (ret != 0) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = ret; return (-1); } for (uzp = LIST_FIRST(&kz.uk_zones); uzp != NULL; uzp = LIST_NEXT(&uz, uz_link)) { ret = kread(kvm, uzp, &uz, sizeof(uz), 0); if (ret != 0) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = ret; return (-1); } ret = kread(kvm, uzp, ucp_array, sizeof(struct uma_cache) * (mp_maxid + 1), offsetof(struct uma_zone, uz_cpu[0])); if (ret != 0) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = ret; return (-1); } ret = kread_string(kvm, uz.uz_name, name, MEMTYPE_MAXNAME); if (ret != 0) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = ret; return (-1); } if (hint_dontsearch == 0) { mtp = memstat_mtl_find(list, ALLOCATOR_UMA, name); } else mtp = NULL; if (mtp == NULL) mtp = _memstat_mt_allocate(list, ALLOCATOR_UMA, name, mp_maxid + 1); if (mtp == NULL) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = MEMSTAT_ERROR_NOMEMORY; return (-1); } /* * Reset the statistics on a current node. */ _memstat_mt_reset_stats(mtp, mp_maxid + 1); mtp->mt_numallocs = uz.uz_allocs; mtp->mt_numfrees = uz.uz_frees; mtp->mt_failures = uz.uz_fails; mtp->mt_sleeps = uz.uz_sleeps; if (kz.uk_flags & UMA_ZFLAG_INTERNAL) goto skip_percpu; for (i = 0; i < mp_maxid + 1; i++) { if (!CPU_ISSET(i, &all_cpus)) continue; ucp = &ucp_array[i]; mtp->mt_numallocs += ucp->uc_allocs; mtp->mt_numfrees += ucp->uc_frees; if (ucp->uc_allocbucket != NULL) { ret = kread(kvm, ucp->uc_allocbucket, &ub, sizeof(ub), 0); if (ret != 0) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = ret; return (-1); } mtp->mt_free += ub.ub_cnt; } if (ucp->uc_freebucket != NULL) { ret = kread(kvm, ucp->uc_freebucket, &ub, sizeof(ub), 0); if (ret != 0) { free(ucp_array); _memstat_mtl_empty(list); list->mtl_error = ret; return (-1); } mtp->mt_free += ub.ub_cnt; } } skip_percpu: mtp->mt_size = kz.uk_size; mtp->mt_memalloced = mtp->mt_numallocs * mtp->mt_size; mtp->mt_memfreed = mtp->mt_numfrees * mtp->mt_size; mtp->mt_bytes = mtp->mt_memalloced - mtp->mt_memfreed; if (kz.uk_ppera > 1) mtp->mt_countlimit = kz.uk_maxpages / kz.uk_ipers; else mtp->mt_countlimit = kz.uk_maxpages * kz.uk_ipers; mtp->mt_byteslimit = mtp->mt_countlimit * mtp->mt_size; mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees; for (ubp = LIST_FIRST(&uz.uz_buckets); ubp != NULL; ubp = LIST_NEXT(&ub, ub_link)) { ret = kread(kvm, ubp, &ub, sizeof(ub), 0); mtp->mt_zonefree += ub.ub_cnt; } if (!((kz.uk_flags & UMA_ZONE_SECONDARY) && LIST_FIRST(&kz.uk_zones) != uzp)) { mtp->mt_kegfree = kz.uk_free; mtp->mt_free += mtp->mt_kegfree; } mtp->mt_free += mtp->mt_zonefree; } } free(ucp_array); return (0); } freebsd-libs-10.1~svn273304/lib/libutil/0000755000000000000000000000000012421417323014503 5ustar freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getfile.30000644000000000000000000000501512366020113017370 0ustar .\" .\" Copyright (c) 2008 Peter Wemm .\" 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. .\" .\" $FreeBSD$ .\" .Dd December 6, 2008 .Dt KINFO_GETFILE 3 .Os .Sh NAME .Nm kinfo_getfile .Nd function for getting per-process file descriptor information .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft struct kinfo_file * .Fn kinfo_getfile "pid_t pid" "int *cntp" .Sh DESCRIPTION This function is used for obtaining the file descriptor information of a particular process. .Pp The .Ar pid field contains the process identifier. This should be the a process that you have privilege to access. The .Ar cntp field allows the caller to know how many records are returned. .Pp This function is a wrapper around .Xr sysctl 3 with the .Dv KERN_PROC_FILEDESC mib. While the kernel returns a packed structure, this function expands the data into a fixed record format. .Sh RETURN VALUES On success the .Fn kinfo_getfile function returns a pointer to an array of .Vt struct kinfo_file structures as defined by .In sys/user.h . The array was obtained by an internal call to .Xr malloc 3 and must be freed by the caller with a call to .Xr free 3 . On failure the .Fn kinfo_getfile function returns .Dv NULL . .Sh SEE ALSO .Xr free 3 , .Xr kinfo_getvmmap 3 , .Xr malloc 3 , .Xr sysctl 3 freebsd-libs-10.1~svn273304/lib/libutil/humanize_number.c0000644000000000000000000001242012224632101020030 0ustar /* $NetBSD: humanize_number.c,v 1.14 2008/04/28 20:22:59 martin Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc. * Copyright 2013 John-Mark Gurney * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include static const int maxscale = 7; int humanize_number(char *buf, size_t len, int64_t quotient, const char *suffix, int scale, int flags) { const char *prefixes, *sep; int i, r, remainder, s1, s2, sign; int divisordeccut; int64_t divisor, max; size_t baselen; /* Since so many callers don't check -1, NUL terminate the buffer */ if (len > 0) buf[0] = '\0'; /* validate args */ if (buf == NULL || suffix == NULL) return (-1); if (scale < 0) return (-1); else if (scale >= maxscale && ((scale & ~(HN_AUTOSCALE|HN_GETSCALE)) != 0)) return (-1); if ((flags & HN_DIVISOR_1000) && (flags & HN_IEC_PREFIXES)) return (-1); /* setup parameters */ remainder = 0; if (flags & HN_IEC_PREFIXES) { baselen = 2; /* * Use the prefixes for power of two recommended by * the International Electrotechnical Commission * (IEC) in IEC 80000-3 (i.e. Ki, Mi, Gi...). * * HN_IEC_PREFIXES implies a divisor of 1024 here * (use of HN_DIVISOR_1000 would have triggered * an assertion earlier). */ divisor = 1024; divisordeccut = 973; /* ceil(.95 * 1024) */ if (flags & HN_B) prefixes = "B\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei"; else prefixes = "\0\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei"; } else { baselen = 1; if (flags & HN_DIVISOR_1000) { divisor = 1000; divisordeccut = 950; if (flags & HN_B) prefixes = "B\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E"; else prefixes = "\0\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E"; } else { divisor = 1024; divisordeccut = 973; /* ceil(.95 * 1024) */ if (flags & HN_B) prefixes = "B\0\0K\0\0M\0\0G\0\0T\0\0P\0\0E"; else prefixes = "\0\0\0K\0\0M\0\0G\0\0T\0\0P\0\0E"; } } #define SCALE2PREFIX(scale) (&prefixes[(scale) * 3]) if (quotient < 0) { sign = -1; quotient = -quotient; baselen += 2; /* sign, digit */ } else { sign = 1; baselen += 1; /* digit */ } if (flags & HN_NOSPACE) sep = ""; else { sep = " "; baselen++; } baselen += strlen(suffix); /* Check if enough room for `x y' + suffix + `\0' */ if (len < baselen + 1) return (-1); if (scale & (HN_AUTOSCALE | HN_GETSCALE)) { /* See if there is additional columns can be used. */ for (max = 1, i = len - baselen; i-- > 0;) max *= 10; /* * Divide the number until it fits the given column. * If there will be an overflow by the rounding below, * divide once more. */ for (i = 0; (quotient >= max || (quotient == max - 1 && remainder >= divisordeccut)) && i < maxscale; i++) { remainder = quotient % divisor; quotient /= divisor; } if (scale & HN_GETSCALE) return (i); } else { for (i = 0; i < scale && i < maxscale; i++) { remainder = quotient % divisor; quotient /= divisor; } } /* If a value <= 9.9 after rounding and ... */ /* * XXX - should we make sure there is enough space for the decimal * place and if not, don't do HN_DECIMAL? */ if (((quotient == 9 && remainder < divisordeccut) || quotient < 9) && i > 0 && flags & HN_DECIMAL) { s1 = (int)quotient + ((remainder * 10 + divisor / 2) / divisor / 10); s2 = ((remainder * 10 + divisor / 2) / divisor) % 10; r = snprintf(buf, len, "%d%s%d%s%s%s", sign * s1, localeconv()->decimal_point, s2, sep, SCALE2PREFIX(i), suffix); } else r = snprintf(buf, len, "%" PRId64 "%s%s%s", sign * (quotient + (remainder + divisor / 2) / divisor), sep, SCALE2PREFIX(i), suffix); return (r); } freebsd-libs-10.1~svn273304/lib/libutil/realhostname.30000644000000000000000000000563511705112725017264 0ustar .\" Copyright (c) 1999 Brian Somers .\" 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. .\" .\" $FreeBSD$ .\" .Dd April 6, 1999 .Dt REALHOSTNAME 3 .Os .Sh NAME .Nm realhostname .Nd "convert an IP number to the real host name" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In libutil.h .Ft int .Fn realhostname "char *host" "size_t hsize" "const struct in_addr *ip" .Sh DESCRIPTION The function .Fn realhostname converts .Ar ip to the corresponding host name. This is done by resolving .Ar ip to a host name and then ensuring that the host name resolves back to .Ar ip . .Pp .Ar host must point to a buffer of at least .Ar hsize bytes, and will always be written to by this function. .Pp If the name resolution does not work both ways or if the host name is longer than .Ar hsize bytes, .Xr inet_ntoa 3 is used to convert .Ar ip to an ASCII form. .Pp If the string written to .Ar host is .Ar hsize bytes long, .Ar host will not be NUL terminated. .Sh RETURN VALUES The .Fn realhostname function will return one of the following constants which are defined in .In libutil.h : .Bl -tag -width XXX -offset XXX .It Li HOSTNAME_FOUND A valid host name was found. .It Li HOSTNAME_INCORRECTNAME A host name was found, but it did not resolve back to the passed .Ar ip . .Ar host now contains the numeric value of .Ar ip . .It Li HOSTNAME_INVALIDADDR .Ar ip could not be resolved. .Ar host now contains the numeric value of .Ar ip . .It Li HOSTNAME_INVALIDNAME A host name was found, but it could not be resolved back to any ip number. .Ar host now contains the numeric value of .Ar ip . .El .Sh SEE ALSO .Xr gethostbyaddr 3 , .Xr gethostbyname 3 , .Xr inet_ntoa 3 , .Xr realhostname_sa 3 freebsd-libs-10.1~svn273304/lib/libutil/login_crypt.c0000644000000000000000000000357107454274530017221 0ustar /*- * Copyright (c) 2000 Brian Fundakowski Feldman * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include const char * login_setcryptfmt(login_cap_t *lc, const char *def, const char *error) { const char *cipher; cipher = login_getcapstr(lc, "passwd_format", def, NULL); if (getenv("CRYPT_DEBUG") != NULL) fprintf(stderr, "login_setcryptfmt: " "passwd_format = %s\n", cipher); if (cipher == NULL) return (error); if (!crypt_set_format(cipher)) return (error); return (cipher); } freebsd-libs-10.1~svn273304/lib/libutil/realhostname.c0000644000000000000000000001304611112657655017347 0ustar /*- * Copyright (c) 1999 Brian Somers * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include "libutil.h" struct sockinet { u_char si_len; u_char si_family; u_short si_port; }; int realhostname(char *host, size_t hsize, const struct in_addr *ip) { char trimmed[MAXHOSTNAMELEN]; int result; struct hostent *hp; result = HOSTNAME_INVALIDADDR; hp = gethostbyaddr((const char *)ip, sizeof(*ip), AF_INET); if (hp != NULL) { strlcpy(trimmed, hp->h_name, sizeof(trimmed)); trimdomain(trimmed, strlen(trimmed)); if (strlen(trimmed) <= hsize) { char lookup[MAXHOSTNAMELEN]; strlcpy(lookup, hp->h_name, sizeof(lookup)); hp = gethostbyname(lookup); if (hp == NULL) result = HOSTNAME_INVALIDNAME; else for (; ; hp->h_addr_list++) { if (*hp->h_addr_list == NULL) { result = HOSTNAME_INCORRECTNAME; break; } if (!memcmp(*hp->h_addr_list, ip, sizeof(*ip))) { strncpy(host, trimmed, hsize); return HOSTNAME_FOUND; } } } } strncpy(host, inet_ntoa(*ip), hsize); return result; } /* * struct sockaddr has very lax alignment requirements, since all its * members are char or equivalent. This is a problem when trying to * dereference a struct sockaddr_in6 * that was passed in as a struct * sockaddr *. Although we know (or trust) that the passed-in struct was * properly aligned, the compiler doesn't, and (rightly) complains. These * macros perform the cast in a way that the compiler will accept. */ #define SOCKADDR_IN6(p) ((struct sockaddr_in6 *)(void *)(p)) #define SOCKADDR_IN(p) ((struct sockaddr_in *)(void *)(p)) #define SOCKINET(p) ((struct sockinet *)(void *)(p)) int realhostname_sa(char *host, size_t hsize, struct sockaddr *addr, int addrlen) { int result, error; char buf[NI_MAXHOST]; #ifdef INET6 struct sockaddr_in lsin; #endif result = HOSTNAME_INVALIDADDR; #ifdef INET6 /* IPv4 mapped IPv6 addr consideraton, specified in rfc2373. */ if (addr->sa_family == AF_INET6 && addrlen == sizeof(struct sockaddr_in6) && IN6_IS_ADDR_V4MAPPED(&SOCKADDR_IN6(addr)->sin6_addr)) { struct sockaddr_in6 *sin6; sin6 = SOCKADDR_IN6(addr); memset(&lsin, 0, sizeof(lsin)); lsin.sin_len = sizeof(struct sockaddr_in); lsin.sin_family = AF_INET; lsin.sin_port = sin6->sin6_port; memcpy(&lsin.sin_addr, &sin6->sin6_addr.s6_addr[12], sizeof(struct in_addr)); addr = (struct sockaddr *)&lsin; addrlen = lsin.sin_len; } #endif error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, NI_NAMEREQD); if (error == 0) { struct addrinfo hints, *res, *ores; struct sockaddr *sa; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = addr->sa_family; hints.ai_flags = AI_CANONNAME | AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(buf, NULL, &hints, &res); if (error) { result = HOSTNAME_INVALIDNAME; goto numeric; } for (ores = res; ; res = res->ai_next) { if (res == NULL) { freeaddrinfo(ores); result = HOSTNAME_INCORRECTNAME; goto numeric; } sa = res->ai_addr; if (sa == NULL) { freeaddrinfo(ores); result = HOSTNAME_INCORRECTNAME; goto numeric; } if (sa->sa_len == addrlen && sa->sa_family == addr->sa_family) { SOCKINET(sa)->si_port = SOCKINET(addr)->si_port; #ifdef INET6 /* * XXX: sin6_socpe_id may not been * filled by DNS */ if (sa->sa_family == AF_INET6 && SOCKADDR_IN6(sa)->sin6_scope_id == 0) SOCKADDR_IN6(sa)->sin6_scope_id = SOCKADDR_IN6(addr)->sin6_scope_id; #endif if (!memcmp(sa, addr, sa->sa_len)) { result = HOSTNAME_FOUND; if (ores->ai_canonname == NULL) { freeaddrinfo(ores); goto numeric; } strlcpy(buf, ores->ai_canonname, sizeof(buf)); trimdomain(buf, hsize); if (strlen(buf) > hsize && addr->sa_family == AF_INET) { freeaddrinfo(ores); goto numeric; } strncpy(host, buf, hsize); break; } } } freeaddrinfo(ores); } else { numeric: if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST) == 0) strncpy(host, buf, hsize); } return result; } freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getfile.c0000644000000000000000000000255711125406627017472 0ustar #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "libutil.h" struct kinfo_file * kinfo_getfile(pid_t pid, int *cntp) { int mib[4]; int error; int cnt; size_t len; char *buf, *bp, *eb; struct kinfo_file *kif, *kp, *kf; *cntp = 0; len = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_FILEDESC; mib[3] = pid; error = sysctl(mib, 4, NULL, &len, NULL, 0); if (error) return (NULL); len = len * 4 / 3; buf = malloc(len); if (buf == NULL) return (NULL); error = sysctl(mib, 4, buf, &len, NULL, 0); if (error) { free(buf); return (NULL); } /* Pass 1: count items */ cnt = 0; bp = buf; eb = buf + len; while (bp < eb) { kf = (struct kinfo_file *)(uintptr_t)bp; bp += kf->kf_structsize; cnt++; } kif = calloc(cnt, sizeof(*kif)); if (kif == NULL) { free(buf); return (NULL); } bp = buf; eb = buf + len; kp = kif; /* Pass 2: unpack */ while (bp < eb) { kf = (struct kinfo_file *)(uintptr_t)bp; /* Copy/expand into pre-zeroed buffer */ memcpy(kp, kf, kf->kf_structsize); /* Advance to next packed record */ bp += kf->kf_structsize; /* Set field size to fixed length, advance */ kp->kf_structsize = sizeof(*kp); kp++; } free(buf); *cntp = cnt; return (kif); /* Caller must free() return value */ } freebsd-libs-10.1~svn273304/lib/libutil/humanize_number.30000644000000000000000000001274212224632101017757 0ustar .\" $NetBSD: humanize_number.3,v 1.4 2003/04/16 13:34:37 wiz Exp $ .\" $FreeBSD$ .\" .\" Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation .\" by Luke Mewburn and by Tomas Svensson. .\" .\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. .\" .Dd October 7, 2013 .Dt HUMANIZE_NUMBER 3 .Os .Sh NAME .Nm humanize_number .Nd format a number into a human readable form .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In libutil.h .Ft int .Fo humanize_number .Fa "char *buf" "size_t len" "int64_t number" "const char *suffix" .Fa "int scale" "int flags" .Fc .Sh DESCRIPTION The .Fn humanize_number function formats the signed 64-bit quantity given in .Fa number into .Fa buf . A space and then .Fa suffix is appended to the end. The buffer pointed to by .Fa buf must be at least .Fa len bytes long. .Pp If the formatted number (including .Fa suffix ) would be too long to fit into .Fa buf , then divide .Fa number by 1024 until it will. In this case, prefix .Fa suffix with the appropriate designator. The .Fn humanize_number function follows the traditional computer science conventions by default, rather than the IEE/IEC (and now also SI) power of two convention or the power of ten notion. This behaviour however can be altered by specifying the .Dv HN_DIVISOR_1000 and .Dv HN_IEC_PREFIXES flags. .Pp The traditional .Pq default prefixes are: .Bl -column "Prefix" "Description" "1000000000000000000" -offset indent .It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier" Ta Sy "Multiplier 1000x" .It Li (note) Ta No kilo Ta 1024 Ta 1000 .It Li M Ta No mega Ta 1048576 Ta 1000000 .It Li G Ta No giga Ta 1073741824 Ta 1000000000 .It Li T Ta No tera Ta 1099511627776 Ta 1000000000000 .It Li P Ta No peta Ta 1125899906842624 Ta 1000000000000000 .It Li E Ta No exa Ta 1152921504606846976 Ta 1000000000000000000 .El .Pp Note: An uppercase K indicates a power of two, a lowercase k a power of ten. .Pp The IEE/IEC (and now also SI) power of two prefixes are: .Bl -column "Prefix" "Description" "1000000000000000000" -offset indent .It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier" .It Li Ki Ta No kibi Ta 1024 .It Li Mi Ta No mebi Ta 1048576 .It Li Gi Ta No gibi Ta 1073741824 .It Li Ti Ta No tebi Ta 1099511627776 .It Li Pi Ta No pebi Ta 1125899906842624 .It Li Ei Ta No exbi Ta 1152921504606846976 .El .Pp The .Fa len argument must be at least 4 plus the length of .Fa suffix , in order to ensure a useful result is generated into .Fa buf . To use a specific prefix, specify this as .Fa scale .Po multiplier = 1024 ^ scale; when .Dv HN_DIVISOR_1000 is specified, multiplier = 1000 ^ scale .Pc . This cannot be combined with any of the .Fa scale flags below. .Pp The following flags may be passed in .Fa scale : .Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent .It Dv HN_AUTOSCALE Format the buffer using the lowest multiplier possible. .It Dv HN_GETSCALE Return the prefix index number (the number of times .Fa number must be divided to fit) instead of formatting it to the buffer. .El .Pp The following flags may be passed in .Fa flags : .Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent .It Dv HN_DECIMAL If the final result is less than 10, display it using one decimal place. .It Dv HN_NOSPACE Do not put a space between .Fa number and the prefix. .It Dv HN_B Use .Ql B (bytes) as prefix if the original result does not have a prefix. .It Dv HN_DIVISOR_1000 Divide .Fa number with 1000 instead of 1024. .It Dv HN_IEC_PREFIXES Use the IEE/IEC notion of prefixes (Ki, Mi, Gi...). This flag has no effect when .Dv HN_DIVISOR_1000 is also specified. .El .Sh RETURN VALUES Upon success, the .Nm function returns the number of characters that would have been stored in .Fa buf (excluding the terminating .Dv NUL ) if .Fa buf was large enough, or \-1 upon failure. Even upon failure, the contents of .Fa buf may be modified. If .Dv HN_GETSCALE is specified, the prefix index number will be returned instead. .Sh SEE ALSO .Xr expand_number 3 .Sh STANDARDS The .Dv HN_DIVISOR_1000 and .Dv HN_IEC_PREFIXES flags conform to .Tn ISO/IEC Std\~80000-13:2008 and .Tn IEEE Std\~1541-2002. .Sh HISTORY The .Fn humanize_number function first appeared in .Nx 2.0 and then in .Fx 5.3 . The .Dv HN_IEC_PREFIXES flag was introduced in .Fx 9.0 . freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getproc.c0000644000000000000000000000407311562731133017507 0ustar /*- * Copyright (c) 2009 Ulf Lilleengen * 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "libutil.h" struct kinfo_proc * kinfo_getproc(pid_t pid) { struct kinfo_proc *kipp; int mib[4]; size_t len; len = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = pid; if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) return (NULL); kipp = malloc(len); if (kipp == NULL) return (NULL); if (sysctl(mib, 4, kipp, &len, NULL, 0) < 0) goto bad; if (len != sizeof(*kipp)) goto bad; if (kipp->ki_structsize != sizeof(*kipp)) goto bad; if (kipp->ki_pid != pid) goto bad; return (kipp); bad: free(kipp); return (NULL); } freebsd-libs-10.1~svn273304/lib/libutil/uucplock.30000644000000000000000000001154211361411226016415 0ustar .\" .\" Copyright (c) 1996 Brian Somers .\" .\" 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 DEVELOPERS ``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 DEVELOPERS 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. .\" .\" $FreeBSD$ .\" " .Dd March 30, 1997 .Dt UUCPLOCK 3 .Os .Sh NAME .Nm uu_lock , .Nm uu_unlock , .Nm uu_lockerr .Nd acquire and release control of a serial device .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft int .Fn uu_lock "const char *ttyname" .Ft int .Fn uu_lock_txfr "const char *ttyname" "pid_t pid" .Ft int .Fn uu_unlock "const char *ttyname" .Ft const char * .Fn uu_lockerr "int uu_lockresult" .Sh DESCRIPTION The .Fn uu_lock function attempts to create a lock file called .Pa /var/spool/lock/LCK.. with a suffix given by the passed .Fa ttyname . If the file already exists, it is expected to contain the process id of the locking program. .Pp If the file does not already exist, or the owning process given by the process id found in the lock file is no longer running, .Fn uu_lock will write its own process id into the file and return success. .Pp .Fn uu_lock_txfr transfers lock ownership to another process. .Fn uu_lock must have previously been successful. .Pp .Fn uu_unlock removes the lockfile created by .Fn uu_lock for the given .Fa ttyname . Care should be taken that .Fn uu_lock was successful before calling .Fn uu_unlock . .Pp .Fn uu_lockerr returns an error string representing the error .Fa uu_lockresult , as returned from .Fn uu_lock . .Sh RETURN VALUES .Fn uu_unlock returns 0 on success and -1 on failure. .Pp .Fn uu_lock may return any of the following values: .Pp .Dv UU_LOCK_INUSE : The lock is in use by another process. .Pp .Dv UU_LOCK_OK : The lock was successfully created. .Pp .Dv UU_LOCK_OPEN_ERR : The lock file could not be opened via .Xr open 2 . .Pp .Dv UU_LOCK_READ_ERR : The lock file could not be read via .Xr read 2 . .Pp .Dv UU_LOCK_CREAT_ERR : Cannot create temporary lock file via .Xr creat 2 . .Pp .Dv UU_LOCK_WRITE_ERR : The current process id could not be written to the lock file via a call to .Xr write 2 . .Pp .Dv UU_LOCK_LINK_ERR : Cannot link temporary lock file via .Xr link 2 . .Pp .Dv UU_LOCK_TRY_ERR : Locking attempts are failed after 5 tries. .Pp If a value of .Dv UU_LOCK_OK is passed to .Fn uu_lockerr , an empty string is returned. Otherwise, a string specifying the reason for failure is returned. .Fn uu_lockerr uses the current value of .Va errno to determine the exact error. Care should be made not to allow .Va errno to be changed between calls to .Fn uu_lock and .Fn uu_lockerr . .Pp .Fn uu_lock_txfr may return any of the following values: .Pp .Dv UU_LOCK_OK : The transfer was successful. The specified process now holds the device lock. .Pp .Dv UU_LOCK_OWNER_ERR : The current process does not already own a lock on the specified device. .Pp .Dv UU_LOCK_WRITE_ERR : The new process id could not be written to the lock file via a call to .Xr write 2 . .Sh ERRORS If .Fn uu_lock returns one of the error values above, the global value .Va errno can be used to determine the cause. Refer to the respective manual pages for further details. .Pp .Fn uu_unlock will set the global variable .Va errno to reflect the reason that the lock file could not be removed. Refer to the description of .Xr unlink 2 for further details. .Sh SEE ALSO .Xr lseek 2 , .Xr open 2 , .Xr read 2 , .Xr write 2 .Sh BUGS It is possible that a stale lock is not recognised as such if a new processes is assigned the same processes id as the program that left the stale lock. .Pp The calling process must have write permissions to the .Pa /var/spool/lock directory. There is no mechanism in place to ensure that the permissions of this directory are the same as those of the serial devices that might be locked. freebsd-libs-10.1~svn273304/lib/libutil/login.conf.50000644000000000000000000004004511770110272016627 0ustar .\" Copyright (c) 1996 David Nugent .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, is permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice immediately at the beginning of the file, without modification, .\" 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. .\" 3. This work was done expressly for inclusion into FreeBSD. Other use .\" is permitted provided this notation is included. .\" 4. Absolutely no warranty of function or purpose is made by the author .\" David Nugent. .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" .\" $FreeBSD$ .\" .Dd July 8, 2011 .Dt LOGIN.CONF 5 .Os .Sh NAME .Nm login.conf .Nd login class capability database .Sh SYNOPSIS .Pa /etc/login.conf , .Pa ~/.login_conf .Sh DESCRIPTION .Nm contains various attributes and capabilities of login classes. A login class (an optional annotation against each record in the user account database, .Pa /etc/master.passwd ) determines session accounting, resource limits and user environment settings. It is used by various programs in the system to set up a user's login environment and to enforce policy, accounting and administrative restrictions. It also provides the means by which users are able to be authenticated to the system and the types of authentication available. Attributes in addition to the ones described here are available with third-party packages. .Pp A special record "default" in the system user class capability database .Pa /etc/login.conf is used automatically for any non-root user without a valid login class in .Pa /etc/master.passwd . A user with a uid of 0 without a valid login class will use the record "root" if it exists, or "default" if not. .Pp In .Fx , users may individually create a file called .Pa .login_conf in their home directory using the same format, consisting of a single entry with a record id of "me". If present, this file is used by .Xr login 1 to set user-defined environment settings which override those specified in the system login capabilities database. Only a subset of login capabilities may be overridden, typically those which do not involve authentication, resource limits and accounting. .Pp Records in a class capabilities database consist of a number of colon-separated fields. The first entry for each record gives one or more names that a record is to be known by, each separated by a '|' character. The first name is the most common abbreviation. The last name given should be a long name that is more descriptive of the capability entry, and all others are synonyms. All names but the last should be in lower case and contain no blanks; the last name may contain upper case characters and blanks for readability. .Pp Note that since a colon .Pq Ql :\& is used to separate capability entries, a .Ql \ec escape sequence must be used to embed a literal colon in the value or name of a capability. .Pp The default .Pa /etc/login.conf shipped with .Fx is an out of the box configuration. Whenever changes to this, or the user's .Pa ~/.login_conf , file are made, the modifications will not be picked up until .Xr cap_mkdb 1 is used to compile the file into a database. This database file will have a .Pa .db extension and is accessed through .Xr cgetent 3 . See .Xr getcap 3 for a more in-depth description of the format of a capability database. .Sh CAPABILITIES Fields within each record in the database follow the .Xr getcap 3 conventions for boolean, type string .Ql \&= and type numeric .Ql \&# , although type numeric is deprecated in favour of the string format and either form is accepted for a numeric datum. Values fall into the following categories: .Bl -tag -width "program" .It bool If the name is present, then the boolean value is true; otherwise, it is false .It file Path name to a data file .It program Path name to an executable file .It list A list of values (or pairs of values) separated by commas or spaces .It path A space or comma separated list of path names, following the usual csh conventions (leading tilde with and without username being expanded to home directories etc.) .It number A numeric value, either decimal (default), hexadecimal (with leading 0x), or octal (with a leading 0). With a numeric type, only one numeric value is allowed. Numeric types may also be specified in string format (i.e., the capability tag being delimited from the value by '=' instead of '#'). Whichever method is used, then all records in the database must use the same method to allow values to be correctly overridden in interpolated records. .It size A number which expresses a size. The default interpretation of a value is the number of bytes, but a suffix may specify alternate units: .Bl -tag -offset indent -compact -width xxxx .It b explicitly selects 512-byte blocks .It k selects kilobytes (1024 bytes) .It m specifies a multiplier of 1 megabyte (1048576 bytes), .It g specifies units of gigabytes, and .It t represents terabytes. .El A size value is a numeric quantity and case of the suffix is not significant. Concatenated values are added together. .It time A period of time, by default in seconds. A prefix may specify a different unit: .Bl -tag -offset indent -compact -width xxxx .It y indicates the number of 365 day years, .It w indicates the number of weeks, .It d the number of days, .It h the number of hours, .It m the number of minutes, and .It s the number of seconds. .El Concatenated values are added together. For example, 2 hours and 40 minutes may be written either as 9600s, 160m or 2h40m. .El .Pp The usual convention to interpolate capability entries using the special .Em tc=value notation may be used. .Sh RESOURCE LIMITS .Bl -column pseudoterminals indent indent .It Sy "Name Type Notes Description" .It "coredumpsize size Maximum coredump size limit." .It "cputime time CPU usage limit." .It "datasize size Maximum data size limit." .It "filesize size Maximum file size limit." .It "maxproc number Maximum number of processes." .It "memorylocked size Maximum locked in core memory size limit." .It "memoryuse size Maximum of core memory use size limit." .It "openfiles number Maximum number of open files per process." .It "sbsize size Maximum permitted socketbuffer size." .It "vmemoryuse size Maximum permitted total VM usage per process." .It "stacksize size Maximum stack size limit." .It "pseudoterminals number Maximum number of pseudo-terminals." .It "swapuse size Maximum swap space size limit." .El .Pp These resource limit entries actually specify both the maximum and current limits (see .Xr getrlimit 2 ) . The current (soft) limit is the one normally used, although the user is permitted to increase the current limit to the maximum (hard) limit. The maximum and current limits may be specified individually by appending a -max or -cur to the capability name. .Sh ENVIRONMENT .Bl -column ignorenologin indent xbinxxusrxbin .It Sy "Name Type Notes Description" .It "charset string Set $MM_CHARSET environment variable to the specified" value. .It "cpumask string List of cpus to bind the user to." The syntax is the same as for the .Fl l argument of .Xr cpuset 1 or the word .Ql default . If set to .Ql default no action is taken. .It "hushlogin bool false Same as having a ~/.hushlogin file." .It "ignorenologin bool false Login not prevented by nologin." .It "ftp-chroot bool false Limit FTP access with" .Xr chroot 2 to the .Ev HOME directory of the user. See .Xr ftpd 8 for details. .It "label string Default MAC policy; see" .Xr maclabel 7 . .It "lang string Set $LANG environment variable to the specified value." .It "manpath path Default search path for manpages." .It "nocheckmail bool false Display mail status at login." .It "nologin file If the file exists it will be displayed and" the login session will be terminated. .It "path path /bin /usr/bin Default search path." .It "priority number Initial priority (nice) level." .It "requirehome bool false Require a valid home directory to login." .It "setenv list A comma-separated list of environment variables and" values to which they are to be set. .It "shell prog Session shell to execute rather than the" shell specified in the passwd file. The SHELL environment variable will contain the shell specified in the password file. .It "term string Default terminal type if not able to determine" from other means. .It "timezone string Default value of $TZ environment variable." .It "umask number 022 Initial umask. Should always have a leading 0 to" ensure octal interpretation. .It "welcome file /etc/motd File containing welcome message." .El .Sh AUTHENTICATION .Bl -column passwd_prompt indent indent .It Sy "Name Type Notes Description" .\" .It "approve program Program to approve login. .It "copyright file File containing additional copyright information" .It "host.allow list List of remote host wildcards from which users in" the class may access. .It "host.deny list List of remote host wildcards from which users" in the class may not access. .It "login_prompt string The login prompt given by" .Xr login 1 .It "login-backoff number 3 The number of login attempts" allowed before the backoff delay is inserted after each subsequent attempt. The backoff delay is the number of tries above .Em login-backoff multiplied by 5 seconds. .It "login-retries number 10 The number of login attempts" allowed before the login fails. .It "passwd_format string sha512 The encryption format that new or" changed passwords will use. Valid values include "des", "md5", "blf", "sha256" and "sha512"; see .Xr crypt 3 for details. NIS clients using a .No non- Ns Fx NIS server should probably use "des". .It "passwd_prompt string The password prompt presented by" .Xr login 1 .It "times.allow list List of time periods during which" logins are allowed. .It "times.deny list List of time periods during which logins are" disallowed. .It "ttys.allow list List of ttys and ttygroups which users" in the class may use for access. .It "ttys.deny list List of ttys and ttygroups which users" in the class may not use for access. .It "warnexpire time Advance notice for pending account expiry." .It "warnpassword time Advance notice for pending password expiry." .\".It "widepasswords bool false Use the wide password format. The wide password .\" format allows up to 128 significant characters in the password. .El .Pp These fields are intended to be used by .Xr passwd 1 and other programs in the login authentication system. .Pp Capabilities that set environment variables are scanned for both .Ql \&~ and .Ql \&$ characters, which are substituted for a user's home directory and name respectively. To pass these characters literally into the environment variable, escape the character by preceding it with a backslash '\\'. .Pp The .Em host.allow and .Em host.deny entries are comma separated lists used for checking remote access to the system, and consist of a list of hostnames and/or IP addresses against which remote network logins are checked. Items in these lists may contain wildcards in the form used by shell programs for wildcard matching (See .Xr fnmatch 3 for details on the implementation). The check on hosts is made against both the remote system's Internet address and hostname (if available). If both lists are empty or not specified, then logins from any remote host are allowed. If host.allow contains one or more hosts, then only remote systems matching any of the items in that list are allowed to log in. If host.deny contains one or more hosts, then a login from any matching hosts will be disallowed. .Pp The .Em times.allow and .Em times.deny entries consist of a comma-separated list of time periods during which the users in a class are allowed to be logged in. These are expressed as one or more day codes followed by a start and end times expressed in 24 hour format, separated by a hyphen or dash. For example, MoThSa0200-1300 translates to Monday, Thursday and Saturday between the hours of 2 am and 1 p.m.. If both of these time lists are empty, users in the class are allowed access at any time. If .Em times.allow is specified, then logins are only allowed during the periods given. If .Em times.deny is specified, then logins are denied during the periods given, regardless of whether one of the periods specified in .Em times.allow applies. .Pp Note that .Xr login 1 enforces only that the actual login falls within periods allowed by these entries. Further enforcement over the life of a session requires a separate daemon to monitor transitions from an allowed period to a non-allowed one. .Pp The .Em ttys.allow and .Em ttys.deny entries contain a comma-separated list of tty devices (without the /dev/ prefix) that a user in a class may use to access the system, and/or a list of ttygroups (See .Xr getttyent 3 and .Xr ttys 5 for information on ttygroups). If neither entry exists, then the choice of login device used by the user is unrestricted. If only .Em ttys.allow is specified, then the user is restricted only to ttys in the given group or device list. If only .Em ttys.deny is specified, then the user is prevented from using the specified devices or devices in the group. If both lists are given and are non-empty, the user is restricted to those devices allowed by ttys.allow that are not available by ttys.deny. .Pp The .Em minpasswordlen and .Em minpasswordcase facilities for enforcing restrictions on password quality, which used to be supported by .Nm , have been superseded by the .Xr pam_passwdqc 8 PAM module. .Sh RESERVED CAPABILITIES The following capabilities are reserved for the purposes indicated and may be supported by third-party software. They are not implemented in the base system. .Bl -column host.accounted indent indent .It Sy "Name Type Notes Description" .It "accounted bool false Enable session time accounting for all users" in this class. .It "auth list passwd Allowed authentication styles." The first item is the default style. .It "auth-" Ns Ar type Ta "list Allowed authentication styles for the" authentication .Ar type . .It "autodelete time Time after expiry when account is auto-deleted." .It "bootfull bool false Enable 'boot only if ttygroup is full' strategy" when terminating sessions. .It "daytime time Maximum login time per day." .It "expireperiod time Time for expiry allocation." .It "graceexpire time Grace days for expired account." .It "gracetime time Additional grace login time allowed." .It "host.accounted list List of remote host wildcards from which" login sessions will be accounted. .It "host.exempt list List of remote host wildcards from which" login session accounting is exempted. .It "idletime time Maximum idle time before logout." .It "minpasswordlen number 6 The minimum length a local" password may be. .It "mixpasswordcase bool true Whether" .Xr passwd 1 will warn the user if an all lower case password is entered. .It "monthtime time Maximum login time per month." .It "passwordtime time Used by" .Xr passwd 1 to set next password expiry date. .It "refreshtime time New time allowed on account refresh." .It "refreshperiod str How often account time is refreshed." .It "sessiontime time Maximum login time per session." .It "sessionlimit number Maximum number of concurrent" login sessions on ttys in any group. .It "ttys.accounted list List of ttys and ttygroups for which" login accounting is active. .It "ttys.exempt list List of ttys and ttygroups for which login accounting" is exempt. .It "warntime time Advance notice for pending out-of-time." .It "weektime time Maximum login time per week." .El .Pp The .Em ttys.accounted and .Em ttys.exempt fields operate in a similar manner to .Em ttys.allow and .Em ttys.deny as explained above. Similarly with the .Em host.accounted and .Em host.exempt lists. .Sh SEE ALSO .Xr cap_mkdb 1 , .Xr login 1 , .Xr chroot 2 , .Xr getcap 3 , .Xr getttyent 3 , .Xr login_cap 3 , .Xr login_class 3 , .Xr pam 3 , .Xr passwd 5 , .Xr ttys 5 , .Xr ftpd 8 , .Xr pam_passwdqc 8 freebsd-libs-10.1~svn273304/lib/libutil/login_cap.h0000644000000000000000000001437611534427503016627 0ustar /*- * Copyright (c) 1996 by * Sean Eric Fagan * David Nugent * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * 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. * 3. This work was done expressly for inclusion into FreeBSD. Other use * is permitted provided this notation is included. * 4. Absolutely no warranty of function or purpose is made by the authors. * 5. Modifications may be freely made to this file providing the above * conditions are met. * * Low-level routines relating to the user capabilities database * * Was login_cap.h,v 1.9 1997/05/07 20:00:01 eivind Exp * $FreeBSD$ */ #ifndef _LOGIN_CAP_H_ #define _LOGIN_CAP_H_ #define LOGIN_DEFCLASS "default" #define LOGIN_DEFROOTCLASS "root" #define LOGIN_MECLASS "me" #define LOGIN_DEFSTYLE "passwd" #define LOGIN_DEFSERVICE "login" #define LOGIN_DEFUMASK 022 #define LOGIN_DEFPRI 0 #define _PATH_LOGIN_CONF "/etc/login.conf" #define _FILE_LOGIN_CONF ".login_conf" #define _PATH_AUTHPROG "/usr/libexec/login_" #define LOGIN_SETGROUP 0x0001 /* set group */ #define LOGIN_SETLOGIN 0x0002 /* set login (via setlogin) */ #define LOGIN_SETPATH 0x0004 /* set path */ #define LOGIN_SETPRIORITY 0x0008 /* set priority */ #define LOGIN_SETRESOURCES 0x0010 /* set resources (cputime, etc.) */ #define LOGIN_SETUMASK 0x0020 /* set umask, obviously */ #define LOGIN_SETUSER 0x0040 /* set user (via setuid) */ #define LOGIN_SETENV 0x0080 /* set user environment */ #define LOGIN_SETMAC 0x0100 /* set user default MAC label */ #define LOGIN_SETCPUMASK 0x0200 /* set user cpumask */ #define LOGIN_SETLOGINCLASS 0x0400 /* set login class in the kernel */ #define LOGIN_SETALL 0x07ff /* set everything */ #define BI_AUTH "authorize" /* accepted authentication */ #define BI_REJECT "reject" /* rejected authentication */ #define BI_CHALLENG "reject challenge" /* reject with a challenge */ #define BI_SILENT "reject silent" /* reject silently */ #define BI_REMOVE "remove" /* remove file on error */ #define BI_ROOTOKAY "authorize root" /* root authenticated */ #define BI_SECURE "authorize secure" /* okay on non-secure line */ #define BI_SETENV "setenv" /* set environment variable */ #define BI_VALUE "value" /* set local variable */ #define AUTH_OKAY 0x01 /* user authenticated */ #define AUTH_ROOTOKAY 0x02 /* root login okay */ #define AUTH_SECURE 0x04 /* secure login */ #define AUTH_SILENT 0x08 /* silent rejection */ #define AUTH_CHALLENGE 0x10 /* a chellenge was given */ #define AUTH_ALLOW (AUTH_OKAY | AUTH_ROOTOKAY | AUTH_SECURE) typedef struct login_cap { char *lc_class; char *lc_cap; char *lc_style; } login_cap_t; typedef struct login_time { u_short lt_start; /* Start time */ u_short lt_end; /* End time */ #define LTM_NONE 0x00 #define LTM_SUN 0x01 #define LTM_MON 0x02 #define LTM_TUE 0x04 #define LTM_WED 0x08 #define LTM_THU 0x10 #define LTM_FRI 0x20 #define LTM_SAT 0x40 #define LTM_ANY 0x7F #define LTM_WK 0x3E #define LTM_WD 0x41 u_char lt_dow; /* Days of week */ } login_time_t; #define LC_MAXTIMES 64 #include __BEGIN_DECLS struct passwd; void login_close(login_cap_t *); login_cap_t *login_getclassbyname(const char *, const struct passwd *); login_cap_t *login_getclass(const char *); login_cap_t *login_getpwclass(const struct passwd *); login_cap_t *login_getuserclass(const struct passwd *); const char *login_getcapstr(login_cap_t *, const char *, const char *, const char *); const char **login_getcaplist(login_cap_t *, const char *, const char *); const char *login_getstyle(login_cap_t *, const char *, const char *); rlim_t login_getcaptime(login_cap_t *, const char *, rlim_t, rlim_t); rlim_t login_getcapnum(login_cap_t *, const char *, rlim_t, rlim_t); rlim_t login_getcapsize(login_cap_t *, const char *, rlim_t, rlim_t); const char *login_getpath(login_cap_t *, const char *, const char *); int login_getcapbool(login_cap_t *, const char *, int); const char *login_setcryptfmt(login_cap_t *, const char *, const char *); int setclasscontext(const char *, unsigned int); void setclasscpumask(login_cap_t *); int setusercontext(login_cap_t *, const struct passwd *, uid_t, unsigned int); void setclassresources(login_cap_t *); void setclassenvironment(login_cap_t *, const struct passwd *, int); /* Most of these functions are deprecated */ int auth_approve(login_cap_t *, const char *, const char *); int auth_check(const char *, const char *, const char *, const char *, int *); void auth_env(void); char *auth_mkvalue(const char *); int auth_response(const char *, const char *, const char *, const char *, int *, const char *, const char *); void auth_rmfiles(void); int auth_scan(int); int auth_script(const char *, ...); int auth_script_data(const char *, int, const char *, ...); char *auth_valud(const char *); int auth_setopt(const char *, const char *); void auth_clropts(void); void auth_checknologin(login_cap_t *); int auth_cat(const char *); int auth_ttyok(login_cap_t *, const char *); int auth_hostok(login_cap_t *, const char *, char const *); int auth_timeok(login_cap_t *, time_t); struct tm; login_time_t parse_lt(const char *); int in_lt(const login_time_t *, time_t *); int in_ltm(const login_time_t *, struct tm *, time_t *); int in_ltms(const login_time_t *, struct tm *, time_t *); int in_lts(const login_time_t *, time_t *); /* helper functions */ int login_strinlist(const char **, char const *, int); int login_str2inlist(const char **, const char *, const char *, int); login_time_t * login_timelist(login_cap_t *, char const *, int *, login_time_t **); int login_ttyok(login_cap_t *, const char *, const char *, const char *); int login_hostok(login_cap_t *, const char *, const char *, const char *, const char *); __END_DECLS #endif /* _LOGIN_CAP_H_ */ freebsd-libs-10.1~svn273304/lib/libutil/pty.30000644000000000000000000000766311361411226015415 0ustar .\" .\" Copyright (c) 1996 Joerg Wunsch .\" .\" 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 DEVELOPERS ``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 DEVELOPERS 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. .\" .\" $FreeBSD$ .\" " .Dd December 29, 1996 .Dt PTY 3 .Os .Sh NAME .Nm openpty , .Nm forkpty .Nd auxiliary functions to obtain a pseudo-terminal .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In sys/ioctl.h .In termios.h .In libutil.h .Ft int .Fn openpty "int *amaster" "int *aslave" "char *name" "struct termios *termp" "struct winsize *winp" .Ft int .Fn forkpty "int *amaster" "char *name" "struct termios *termp" "struct winsize *winp" .Sh DESCRIPTION The function .Fn openpty attempts to obtain the next available pseudo-terminal from the system (see .Xr pty 4 ) . If it successfully finds one, it subsequently changes the ownership of the slave device to the real UID of the current process, the group membership to the group .Dq tty (if such a group exists in the system), the access permissions for reading and writing by the owner, and for writing by the group, and invalidates any current use of the line by calling .Xr revoke 2 . .Pp If the argument .Fa name is not .Dv NULL , .Fn openpty copies the pathname of the slave pty to this area. The caller is responsible for allocating the required space in this array. .Pp If the arguments .Fa termp or .Fa winp are not .Dv NULL , .Fn openpty initializes the termios and window size settings from the structures these arguments point to, respectively. .Pp Upon return, the open file descriptors for the master and slave side of the pty are returned in the locations pointed to by .Fa amaster and .Fa aslave , respectively. .Pp The .Fn forkpty function first calls .Fn openpty to obtain the next available pseudo-terminal from the system. Upon success, it forks off a new process. In the child process, it closes the descriptor for the master side of the pty, and calls .Xr login_tty 3 for the slave pty. In the parent process, it closes the descriptor for the slave side of the pty. The arguments .Fa amaster , .Fa name , .Fa termp , and .Fa winp have the same meaning as described for .Fn openpty . .Sh RETURN VALUES The .Fn openpty function returns 0 on success, or -1 on failure. .Pp The .Fn forkpty function returns -1 on failure, 0 in the slave process, and the process ID of the slave process in the parent process. .Sh ERRORS The .Fn openpty function may fail and set the global variable .Dv errno for any of the errors specified for the .Xr grantpt 3 , .Xr posix_openpt 3 , .Xr ptsname 3 , and .Xr unlockpt 3 functions and the .Xr revoke 2 system call. .Pp In addition to this, .Fn forkpty may set it to any value as described for .Xr fork 2 . .Sh SEE ALSO .Xr chmod 2 , .Xr chown 2 , .Xr fork 2 , .Xr getuid 2 , .Xr open 2 , .Xr revoke 2 , .Xr login_tty 3 , .Xr pty 4 , .Xr termios 4 , .Xr group 5 freebsd-libs-10.1~svn273304/lib/libutil/stub.c0000644000000000000000000000326607744210040015632 0ustar /*- * Copyright (c) 2000 Brian Fundakowski Feldman * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include /* * Stub out what's in -lcrypt. */ #pragma weak crypt_set_format /* ARGSUSED */ int crypt_set_format(const char *f __unused) { if (getenv("CRYPT_DEBUG") != NULL) fprintf(stderr, "crypt_set_format: eek, stub called!\n"); return (0); } freebsd-libs-10.1~svn273304/lib/libutil/pty.c0000644000000000000000000000603311104051472015461 0ustar /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94"; #endif #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #include #include int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) { const char *slavename; int master, slave; master = posix_openpt(O_RDWR|O_NOCTTY); if (master == -1) return (-1); if (grantpt(master) == -1) goto bad; if (unlockpt(master) == -1) goto bad; slavename = ptsname(master); if (slavename == NULL) goto bad; slave = open(slavename, O_RDWR); if (slave == -1) goto bad; *amaster = master; *aslave = slave; if (name) strcpy(name, slavename); if (termp) tcsetattr(slave, TCSAFLUSH, termp); if (winp) ioctl(slave, TIOCSWINSZ, (char *)winp); return (0); bad: close(master); return (-1); } int forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) { int master, slave, pid; if (openpty(&master, &slave, name, termp, winp) == -1) return (-1); switch (pid = fork()) { case -1: return (-1); case 0: /* * child */ (void) close(master); login_tty(slave); return (0); } /* * parent */ *amaster = master; (void) close(slave); return (pid); } freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getproc.30000644000000000000000000000455512114055442017430 0ustar .\" .\" Copyright (c) 2009 Ulf Lilleengen .\" 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. .\" .\" $FreeBSD$ .\" .Dd March 1, 2013 .Dt KINFO_GETPROC 3 .Os .Sh NAME .Nm kinfo_getproc .Nd function for getting process information from kernel .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft struct kinfo_proc * .Fn kinfo_getproc "pid_t pid" .Sh DESCRIPTION This function is used for obtaining process information from the kernel. .Pp The .Ar pid field contains the process identifier. This should be a process that you have privilege to access. This function is a wrapper around .Xr sysctl 3 with the .Dv KERN_PROC_PID mib. While the kernel returns a packed structure, this function expands the data into a fixed record format. .Sh RETURN VALUES On success the .Fn kinfo_getproc function returns a pointer to a .Vt struct kinfo_proc structure as defined by .In sys/user.h . The pointer was obtained by an internal call to .Xr malloc 3 and must be freed by the caller with a call to .Xr free 3 . On failure the .Fn kinfo_getproc function returns .Dv NULL . .Sh SEE ALSO .Xr free 3 , .Xr malloc 3 , .Xr sysctl 3 freebsd-libs-10.1~svn273304/lib/libutil/uucplock.c0000644000000000000000000001301712207463515016504 0ustar /* * Copyright (c) 1988, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #ifndef lint static const char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include "libutil.h" #define MAXTRIES 5 #define LOCKTMP "LCKTMP..%d" #define LOCKFMT "LCK..%s" #define GORET(level, val) { err = errno; uuerr = (val); \ goto __CONCAT(ret, level); } /* Forward declarations */ static int put_pid (int fd, pid_t pid); static pid_t get_pid (int fd,int *err); /* * uucp style locking routines */ int uu_lock(const char *tty_name) { int fd, tmpfd, i; pid_t pid, pid_old; char lckname[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN], lcktmpname[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; int err, uuerr; pid = getpid(); (void)snprintf(lcktmpname, sizeof(lcktmpname), _PATH_UUCPLOCK LOCKTMP, pid); (void)snprintf(lckname, sizeof(lckname), _PATH_UUCPLOCK LOCKFMT, tty_name); if ((tmpfd = open(lcktmpname, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0664)) < 0) GORET(0, UU_LOCK_CREAT_ERR); for (i = 0; i < MAXTRIES; i++) { if (link (lcktmpname, lckname) < 0) { if (errno != EEXIST) GORET(1, UU_LOCK_LINK_ERR); /* * file is already locked * check to see if the process holding the lock * still exists */ if ((fd = open(lckname, O_RDONLY | O_CLOEXEC)) < 0) GORET(1, UU_LOCK_OPEN_ERR); if ((pid_old = get_pid (fd, &err)) == -1) GORET(2, UU_LOCK_READ_ERR); close(fd); if (kill(pid_old, 0) == 0 || errno != ESRCH) GORET(1, UU_LOCK_INUSE); /* * The process that locked the file isn't running, so * we'll lock it ourselves */ (void)unlink(lckname); } else { if (!put_pid (tmpfd, pid)) GORET(3, UU_LOCK_WRITE_ERR); break; } } GORET(1, (i >= MAXTRIES) ? UU_LOCK_TRY_ERR : UU_LOCK_OK); ret3: (void)unlink(lckname); goto ret1; ret2: (void)close(fd); ret1: (void)close(tmpfd); (void)unlink(lcktmpname); ret0: errno = err; return uuerr; } int uu_lock_txfr(const char *tty_name, pid_t pid) { int fd, err; char lckname[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; snprintf(lckname, sizeof(lckname), _PATH_UUCPLOCK LOCKFMT, tty_name); if ((fd = open(lckname, O_RDWR | O_CLOEXEC)) < 0) return UU_LOCK_OWNER_ERR; if (get_pid(fd, &err) != getpid()) err = UU_LOCK_OWNER_ERR; else { lseek(fd, (off_t)0, SEEK_SET); err = put_pid(fd, pid) ? 0 : UU_LOCK_WRITE_ERR; } close(fd); return err; } int uu_unlock(const char *tty_name) { char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; (void)snprintf(tbuf, sizeof(tbuf), _PATH_UUCPLOCK LOCKFMT, tty_name); return unlink(tbuf); } const char * uu_lockerr(int uu_lockresult) { static char errbuf[128]; const char *fmt; switch (uu_lockresult) { case UU_LOCK_INUSE: return "device in use"; case UU_LOCK_OK: return ""; case UU_LOCK_OPEN_ERR: fmt = "open error: %s"; break; case UU_LOCK_READ_ERR: fmt = "read error: %s"; break; case UU_LOCK_CREAT_ERR: fmt = "creat error: %s"; break; case UU_LOCK_WRITE_ERR: fmt = "write error: %s"; break; case UU_LOCK_LINK_ERR: fmt = "link error: %s"; break; case UU_LOCK_TRY_ERR: fmt = "too many tries: %s"; break; case UU_LOCK_OWNER_ERR: fmt = "not locking process: %s"; break; default: fmt = "undefined error: %s"; break; } (void)snprintf(errbuf, sizeof(errbuf), fmt, strerror(errno)); return errbuf; } static int put_pid(int fd, pid_t pid) { char buf[32]; int len; len = sprintf (buf, "%10d\n", (int)pid); return write (fd, buf, (size_t)len) == len; } static pid_t get_pid(int fd, int *err) { int bytes_read; char buf[32]; pid_t pid; bytes_read = read (fd, buf, sizeof (buf) - 1); if (bytes_read > 0) { buf[bytes_read] = '\0'; pid = (pid_t)strtol (buf, (char **) NULL, 10); } else { pid = -1; *err = bytes_read ? errno : EINVAL; } return pid; } /* end of uucplock.c */ freebsd-libs-10.1~svn273304/lib/libutil/libutil.h0000644000000000000000000001747512116161660016337 0ustar /* * Copyright (c) 1996 Peter Wemm . * All rights reserved. * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * * Portions of this software were developed for the FreeBSD Project by * ThinkSec AS and NAI Labs, the Security Research Division of Network * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, is 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. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * 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. * * $FreeBSD$ */ #ifndef _LIBUTIL_H_ #define _LIBUTIL_H_ #include #include #include #ifndef _GID_T_DECLARED typedef __gid_t gid_t; #define _GID_T_DECLARED #endif #ifndef _MODE_T_DECLARED typedef __mode_t mode_t; #define _MODE_T_DECLARED #endif #ifndef _PID_T_DECLARED typedef __pid_t pid_t; #define _PID_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _UID_T_DECLARED typedef __uid_t uid_t; #define _UID_T_DECLARED #endif #define PROPERTY_MAX_NAME 64 #define PROPERTY_MAX_VALUE 512 /* For properties.c. */ typedef struct _property { struct _property *next; char *name; char *value; } *properties; /* Avoid pulling in all the include files for no need. */ struct in_addr; struct pidfh; struct sockaddr; struct termios; struct winsize; __BEGIN_DECLS char *auth_getval(const char *_name); void clean_environment(const char * const *_white, const char * const *_more_white); int expand_number(const char *_buf, uint64_t *_num); int extattr_namespace_to_string(int _attrnamespace, char **_string); int extattr_string_to_namespace(const char *_string, int *_attrnamespace); int flopen(const char *_path, int _flags, ...); int forkpty(int *_amaster, char *_name, struct termios *_termp, struct winsize *_winp); void hexdump(const void *_ptr, int _length, const char *_hdr, int _flags); int humanize_number(char *_buf, size_t _len, int64_t _number, const char *_suffix, int _scale, int _flags); struct kinfo_file * kinfo_getfile(pid_t _pid, int *_cntp); struct kinfo_vmentry * kinfo_getvmmap(pid_t _pid, int *_cntp); struct kinfo_proc * kinfo_getallproc(int *_cntp); struct kinfo_proc * kinfo_getproc(pid_t _pid); int kld_isloaded(const char *_name); int kld_load(const char *_name); int login_tty(int _fd); int openpty(int *_amaster, int *_aslave, char *_name, struct termios *_termp, struct winsize *_winp); int pidfile_close(struct pidfh *_pfh); int pidfile_fileno(const struct pidfh *_pfh); struct pidfh * pidfile_open(const char *_path, mode_t _mode, pid_t *_pidptr); int pidfile_remove(struct pidfh *_pfh); int pidfile_write(struct pidfh *_pfh); void properties_free(properties _list); char *property_find(properties _list, const char *_name); properties properties_read(int _fd); int realhostname(char *_host, size_t _hsize, const struct in_addr *_ip); int realhostname_sa(char *_host, size_t _hsize, struct sockaddr *_addr, int _addrlen); int _secure_path(const char *_path, uid_t _uid, gid_t _gid); void trimdomain(char *_fullhost, int _hostsize); const char * uu_lockerr(int _uu_lockresult); int uu_lock(const char *_ttyname); int uu_unlock(const char *_ttyname); int uu_lock_txfr(const char *_ttyname, pid_t _pid); /* * Conditionally prototype the following functions if the include * files upon which they depend have been included. */ #ifdef _STDIO_H_ char *fparseln(FILE *_fp, size_t *_len, size_t *_lineno, const char _delim[3], int _flags); #endif #ifdef _PWD_H_ int pw_copy(int _ffd, int _tfd, const struct passwd *_pw, struct passwd *_old_pw); struct passwd *pw_dup(const struct passwd *_pw); int pw_edit(int _notsetuid); int pw_equal(const struct passwd *_pw1, const struct passwd *_pw2); void pw_fini(void); int pw_init(const char *_dir, const char *_master); char *pw_make(const struct passwd *_pw); char *pw_make_v7(const struct passwd *_pw); int pw_mkdb(const char *_user); int pw_lock(void); struct passwd * pw_scan(const char *_line, int _flags); const char * pw_tempname(void); int pw_tmp(int _mfd); #endif #ifdef _GRP_H_ int gr_copy(int __ffd, int _tfd, const struct group *_gr, struct group *_old_gr); struct group * gr_dup(const struct group *_gr); struct group * gr_add(const struct group *_gr, const char *_newmember); int gr_equal(const struct group *_gr1, const struct group *_gr2); void gr_fini(void); int gr_init(const char *_dir, const char *_master); int gr_lock(void); char *gr_make(const struct group *_gr); int gr_mkdb(void); struct group * gr_scan(const char *_line); int gr_tmp(int _mdf); #endif #ifdef _UFS_UFS_QUOTA_H_ struct fstab; struct quotafile; int quota_check_path(const struct quotafile *_qf, const char *_path); void quota_close(struct quotafile *_qf); int quota_convert(struct quotafile *_qf, int _wordsize); const char * quota_fsname(const struct quotafile *_qf); int quota_maxid(struct quotafile *_qf); int quota_off(struct quotafile *_qf); int quota_on(struct quotafile *_qf); struct quotafile * quota_open(struct fstab *_fs, int _quotatype, int _openflags); const char * quota_qfname(const struct quotafile *_qf); int quota_read(struct quotafile *_qf, struct dqblk *_dqb, int _id); int quota_write_limits(struct quotafile *_qf, struct dqblk *_dqb, int _id); int quota_write_usage(struct quotafile *_qf, struct dqblk *_dqb, int _id); #endif __END_DECLS /* fparseln(3) */ #define FPARSELN_UNESCESC 0x01 #define FPARSELN_UNESCCONT 0x02 #define FPARSELN_UNESCCOMM 0x04 #define FPARSELN_UNESCREST 0x08 #define FPARSELN_UNESCALL 0x0f /* Flags for hexdump(3). */ #define HD_COLUMN_MASK 0xff #define HD_DELIM_MASK 0xff00 #define HD_OMIT_COUNT (1 << 16) #define HD_OMIT_HEX (1 << 17) #define HD_OMIT_CHARS (1 << 18) /* Values for humanize_number(3)'s flags parameter. */ #define HN_DECIMAL 0x01 #define HN_NOSPACE 0x02 #define HN_B 0x04 #define HN_DIVISOR_1000 0x08 #define HN_IEC_PREFIXES 0x10 /* Values for humanize_number(3)'s scale parameter. */ #define HN_GETSCALE 0x10 #define HN_AUTOSCALE 0x20 /* Return values from realhostname(). */ #define HOSTNAME_FOUND 0 #define HOSTNAME_INCORRECTNAME 1 #define HOSTNAME_INVALIDADDR 2 #define HOSTNAME_INVALIDNAME 3 /* Flags for pw_scan(). */ #define PWSCAN_MASTER 0x01 #define PWSCAN_WARN 0x02 /* Return values from uu_lock(). */ #define UU_LOCK_INUSE 1 #define UU_LOCK_OK 0 #define UU_LOCK_OPEN_ERR (-1) #define UU_LOCK_READ_ERR (-2) #define UU_LOCK_CREAT_ERR (-3) #define UU_LOCK_WRITE_ERR (-4) #define UU_LOCK_LINK_ERR (-5) #define UU_LOCK_TRY_ERR (-6) #define UU_LOCK_OWNER_ERR (-7) #endif /* !_LIBUTIL_H_ */ freebsd-libs-10.1~svn273304/lib/libutil/flopen.c0000644000000000000000000000544311212534647016146 0ustar /*- * Copyright (c) 2007 Dag-Erling Coïdan Smørgrav * 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 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include int flopen(const char *path, int flags, ...) { int fd, operation, serrno, trunc; struct stat sb, fsb; mode_t mode; #ifdef O_EXLOCK flags &= ~O_EXLOCK; #endif mode = 0; if (flags & O_CREAT) { va_list ap; va_start(ap, flags); mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */ va_end(ap); } operation = LOCK_EX; if (flags & O_NONBLOCK) operation |= LOCK_NB; trunc = (flags & O_TRUNC); flags &= ~O_TRUNC; for (;;) { if ((fd = open(path, flags, mode)) == -1) /* non-existent or no access */ return (-1); if (flock(fd, operation) == -1) { /* unsupported or interrupted */ serrno = errno; (void)close(fd); errno = serrno; return (-1); } if (stat(path, &sb) == -1) { /* disappeared from under our feet */ (void)close(fd); continue; } if (fstat(fd, &fsb) == -1) { /* can't happen [tm] */ serrno = errno; (void)close(fd); errno = serrno; return (-1); } if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino) { /* changed under our feet */ (void)close(fd); continue; } if (trunc && ftruncate(fd, 0) != 0) { /* can't happen [tm] */ serrno = errno; (void)close(fd); errno = serrno; return (-1); } return (fd); } } freebsd-libs-10.1~svn273304/lib/libutil/hexdump.30000644000000000000000000000571011361411226016242 0ustar .\" -*- nroff -*- .\" .\" Copyright (c) 2003 Scott Long .\" .\" All rights reserved. .\" .\" This program is free software. .\" .\" 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 DEVELOPERS ``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 DEVELOPERS 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. .\" .\" $FreeBSD$ .\" .Dd July 1, 2008 .Dt HEXDUMP 3 .Os .Sh NAME .Nm hexdump .Nd "dump a block of bytes to standard out in hexadecimal form" .Sh SYNOPSIS .In libutil.h .Ft void .Fn hexdump "void *ptr" "int length" "const char *hdr" "int flags" .Sh DESCRIPTION The .Fn hexdump function prints an array of bytes to standard out in hexadecimal form, along with the .Tn ASCII representation of the bytes, if possible. By default, each line of output will start with an offset count, followed by 16 hexadecimal values, followed by 16 .Tn ASCII characters. .Bl -tag -width indent .It Fa ptr Pointer to the array of bytes to print. It does not need to be .Dv NUL Ns -terminated. .It Fa length Number of bytes to print. .It Fa hdr Pointer to a .Dv NUL Ns -terminated character string that will be prepended to each line of output. A value of .Dv NULL implies that no header will be printed. .It Fa flags Flags for controlling the formatting of the output. .Bl -tag -width ".Dv HD_OMIT_COUNT" .It Bits 0-7 Integer value of the number of bytes to display on each line. A value of 0 implies that the default value of 16 will be used. .It Bits 8-15 Character .Tn ASCII value to use as the separator for the hexadecimal output. A value of 0 implies that the default value of 32 .Tn ( ASCII space) will be used. .It Dv HD_OMIT_COUNT Do not print the offset column at the beginning of each line. .It Dv HD_OMIT_HEX Do not print the hexadecimal values on each line. .It Dv HD_OMIT_CHARS Do not print the character values on each line. .El .El .Sh SEE ALSO .Xr ascii 7 .Sh AUTHORS This manual page was written by .An Scott Long . freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getvmmap.c0000644000000000000000000000257511125406627017673 0ustar #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "libutil.h" struct kinfo_vmentry * kinfo_getvmmap(pid_t pid, int *cntp) { int mib[4]; int error; int cnt; size_t len; char *buf, *bp, *eb; struct kinfo_vmentry *kiv, *kp, *kv; *cntp = 0; len = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_VMMAP; mib[3] = pid; error = sysctl(mib, 4, NULL, &len, NULL, 0); if (error) return (NULL); len = len * 4 / 3; buf = malloc(len); if (buf == NULL) return (NULL); error = sysctl(mib, 4, buf, &len, NULL, 0); if (error) { free(buf); return (NULL); } /* Pass 1: count items */ cnt = 0; bp = buf; eb = buf + len; while (bp < eb) { kv = (struct kinfo_vmentry *)(uintptr_t)bp; bp += kv->kve_structsize; cnt++; } kiv = calloc(cnt, sizeof(*kiv)); if (kiv == NULL) { free(buf); return (NULL); } bp = buf; eb = buf + len; kp = kiv; /* Pass 2: unpack */ while (bp < eb) { kv = (struct kinfo_vmentry *)(uintptr_t)bp; /* Copy/expand into pre-zeroed buffer */ memcpy(kp, kv, kv->kve_structsize); /* Advance to next packed record */ bp += kv->kve_structsize; /* Set field size to fixed length, advance */ kp->kve_structsize = sizeof(*kp); kp++; } free(buf); *cntp = cnt; return (kiv); /* Caller must free() return value */ } freebsd-libs-10.1~svn273304/lib/libutil/login_tty.c0000644000000000000000000000413411324647143016667 0ustar /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)login_tty.c 8.1 (Berkeley) 6/4/93"; #endif #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include int login_tty(int fd) { pid_t s; s = setsid(); if (s == -1) s = getsid(0); if (tcsetsid(fd, s) == -1) return (-1); (void) dup2(fd, 0); (void) dup2(fd, 1); (void) dup2(fd, 2); if (fd > 2) (void) close(fd); return (0); } freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getvmmap.30000644000000000000000000000500611426052171017576 0ustar .\" .\" Copyright (c) 2008 Peter Wemm .\" 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. .\" .\" $FreeBSD$ .\" .Dd December 6, 2008 .Dt KINFO_GETVMMAP 3 .Os .Sh NAME .Nm kinfo_getvmmap .Nd function for getting per-process memory map information .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft struct kinfo_vmentry * .Fn kinfo_getvmmap "pid_t pid" "int *cntp" .Sh DESCRIPTION This function is used for obtaining virtual memory mapping information of a particular process. .Pp The .Ar pid field contains the process identifier. This should be the a process that you have privilege to access. The .Ar cntp field is allows the caller to know how many records are returned. .Pp This function is a wrapper around .Xr sysctl 3 with the .Dv KERN_PROC_VMMAP mib. While the kernel returns a packed structure, this function expands the data into a fixed record format. .Sh RETURN VALUES On success the .Fn kinfo_getvmmap function returns a pointer to an array of .Vt struct kinfo_vmentry structures as defined by .In sys/user.h . The array was obtained by an internal call to .Xr malloc 3 and must be freed by the caller with a call to .Xr free 3 . On failure the .Fn kinfo_getvmmap function returns .Dv NULL . .Sh SEE ALSO .Xr free 3 , .Xr kinfo_getfile 3 , .Xr malloc 3 freebsd-libs-10.1~svn273304/lib/libutil/login_tty.30000644000000000000000000000430311361411226016575 0ustar .\" .\" Copyright (c) 1996 Joerg Wunsch .\" .\" 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 DEVELOPERS ``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 DEVELOPERS 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. .\" .\" $FreeBSD$ .\" " .Dd December 29, 1996 .Dt LOGIN_TTY 3 .Os .Sh NAME .Nm login_tty .Nd prepare a tty for a new login session .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In libutil.h .Ft int .Fn login_tty "int fd" .Sh DESCRIPTION The function .Fn login_tty prepares a terminal for a new login session. The file descriptor .Ar fd passed to .Fn login_tty must be opened for reading and writing on a terminal device. It will be made the controlling terminal for the calling process, after allocating a new session with .Xr setsid 2 . This terminal device will also be made the standard input, standard output, and standard error output of the calling process. .Sh RETURN VALUES The .Fn login_tty function returns -1 if it could not make the device referenced by .Ar fd the controlling terminal of the calling process, and 0 otherwise. .Sh SEE ALSO .Xr dup2 2 , .Xr ioctl 2 , .Xr setsid 2 , .Xr tty 4 freebsd-libs-10.1~svn273304/lib/libutil/flopen.30000644000000000000000000000536511702067504016066 0ustar .\"- .\" Copyright (c) 2007 Dag-Erling Coïdan Smørgrav .\" 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. .\" .\" $FreeBSD$ .\" .Dd June 6, 2009 .Dt FLOPEN 3 .Os .Sh NAME .Nm flopen .Nd "Reliably open and lock a file" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/fcntl.h .In libutil.h .Ft int .Fn flopen "const char *path" "int flags" .Ft int .Fn flopen "const char *path" "int flags" "mode_t mode" .Sh DESCRIPTION The .Fn flopen function opens or creates a file and acquires an exclusive lock on it. It is essentially equivalent with calling .Fn open with the same parameters followed by .Fn flock with an .Va operation argument of .Dv LOCK_EX , except that .Fn flopen will attempt to detect and handle races that may occur between opening / creating the file and locking it. Thus, it is well suited for opening lock files, PID files, spool files, mailboxes and other kinds of files which are used for synchronization between processes. .Pp If .Va flags includes .Dv O_NONBLOCK and the file is already locked, .Fn flopen will fail and set .Va errno to .Dv EWOULDBLOCK . .Pp As with .Fn open , the additional .Va mode argument is required if .Va flags includes .Dv O_CREAT . .Sh RETURN VALUES If successful, .Fn flopen returns a valid file descriptor. Otherwise, it returns -1, and sets .Va errno as described in .Xr flock 2 and .Xr open 2 . .Sh SEE ALSO .Xr errno 2 , .Xr flock 2 , .Xr open 2 .Sh AUTHORS .An -nosplit The .Nm function and this manual page were written by .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org . freebsd-libs-10.1~svn273304/lib/libutil/hexdump.c0000644000000000000000000000567611032530041016325 0ustar /*- * Copyright (c) 1986, 1988, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 */ #include __FBSDID("$FreeBSD$"); #include #include #include void hexdump(const void *ptr, int length, const char *hdr, int flags) { int i, j, k; int cols; const unsigned char *cp; char delim; if ((flags & HD_DELIM_MASK) != 0) delim = (flags & HD_DELIM_MASK) >> 8; else delim = ' '; if ((flags & HD_COLUMN_MASK) != 0) cols = flags & HD_COLUMN_MASK; else cols = 16; cp = ptr; for (i = 0; i < length; i+= cols) { if (hdr != NULL) printf("%s", hdr); if ((flags & HD_OMIT_COUNT) == 0) printf("%04x ", i); if ((flags & HD_OMIT_HEX) == 0) { for (j = 0; j < cols; j++) { k = i + j; if (k < length) printf("%c%02x", delim, cp[k]); else printf(" "); } } if ((flags & HD_OMIT_CHARS) == 0) { printf(" |"); for (j = 0; j < cols; j++) { k = i + j; if (k >= length) printf(" "); else if (cp[k] >= ' ' && cp[k] <= '~') printf("%c", cp[k]); else printf("."); } printf("|"); } printf("\n"); } } freebsd-libs-10.1~svn273304/lib/libutil/property.30000644000000000000000000000564011765673075016502 0ustar .\" .\" Copyright (c) 1998 Jordan Hubbard .\" .\" 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 DEVELOPERS ``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 DEVELOPERS 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. .\" .\" $FreeBSD$ .\" " .Dd October 7, 1998 .Dt PROPERTIES 3 .Os .Sh NAME .Nm properties_read , .Nm property_find , .Nm properties_free .Nd "functions to allow creating simple property lists from ASCII file data" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In libutil.h .Ft properties .Fn properties_read "int fd" .Ft char * .Fn property_find "properties list" "const char *name" .Ft void .Fn properties_free "properties list" .Sh DESCRIPTION .Bd -literal typedef struct _properties { struct _properties *next; char *name; char *value; } *properties; .Ed .Pp The function .Fn properties_read reads .Fa name = value pairs from the file descriptor passed in .Fa fd and returns the head of a new property list, assuming that the file's contents have been parsed properly, or NULL in case of error. .Pp The .Fn property_find function returns the associated value string for the property named .Fa name if found, otherwise NULL. The value returned may be up to .Dv PROPERTY_MAX_VALUE bytes in length. .Pp The .Fn properties_free function is used to free the structure returned by .Fn properties_read when it is no longer needed. .Sh FILE FORMAT Each property in the file is assumed to have the format of .Fa name = value where .Fa name is an alphanumeric string (and any punctuation not including the `=' character) and .Fa value is an arbitrary string of text terminated by a newline character. If newlines are desired, the entire value should be enclosed in { } (curly-bracket) characters. Any line beginning with a # or ; character is assumed to be a comment and will be ignored. .Sh AUTHORS .An Jordan Hubbard .Sh BUGS Simplistic. freebsd-libs-10.1~svn273304/lib/libutil/login_times.30000644000000000000000000001225411361411226017102 0ustar .\" Copyright (c) 1995 David Nugent .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, is permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice immediately at the beginning of the file, without modification, .\" 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. .\" 3. This work was done expressly for inclusion into FreeBSD. Other use .\" is permitted provided this notation is included. .\" 4. Absolutely no warranty of function or purpose is made by the author .\" David Nugent. .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" .\" $FreeBSD$ .\" .Dd October 20, 2008 .Dt LOGIN_TIMES 3 .Os .Sh NAME .Nm parse_lt , .Nm in_lt , .Nm in_ltm , .Nm in_ltms , .Nm in_lts .Nd functions for parsing and checking login time periods .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In time.h .In login_cap.h .Ft login_time_t .Fn parse_lt "const char *str" .Ft int .Fn in_lt "const login_time_t *lt" "time_t *ends" .Ft int .Fn in_ltm "const login_time_t *lt" "struct tm *t" "time_t *ends" .Ft int .Fn in_ltms "const login_time_t *lt" "struct tm *t" "time_t *ends" .Ft int .Fn in_lts "const login_time_t *lt" "time_t *ends" .Sh DESCRIPTION This set of functions may be used for parsing and checking login and session times against a predefined list of allowed login times as used in .Xr login.conf 5 . .Pp The format of allowed and disallowed session times specified in the .Ar times.allow and .Ar times.deny capability fields in a login class are comprised of a prefix which specifies one or more 2- or 3-character day codes, followed by a start and end time in 24 hour format separated by a hyphen. Day codes may be concatenated together to select specific days, or the special mnemonics "Any" and "All" (for any/all days of the week), "Wk" for any day of the week (excluding Saturdays and Sundays) and "Wd" for any weekend day may be used. .Pp For example, the following time period: .Dl MoThFrSa1400-2200 is interpreted as Monday, Thursday through Saturday between the hours of 2pm and 10pm. .Dl Wd0600-1800 means Saturday and Sunday, between the hours of 6am through 6pm, and .Dl Any0400-1600 means any day of the week, between 4am and 4pm. .Pp Note that all time periods reference system local time. .Pp The .Fn parse_lt function converts the ASCII representation of a time period into a structure of type .Ft login_time_t . This is defined as: .Bd -literal typedef struct login_time { u_short lt_start; /* Start time */ u_short lt_end; /* End time */ u_char lt_dow; /* Days of week */ } login_time_t; .Ed .Pp The .Ar lt_start and .Ar lt_end fields contain the number of minutes past midnight at which the described period begins and ends. The .Ar lt_dow field is a bit field, containing one bit for each day of the week and one bit unused. A series .Em LTM_* macros may be used for testing bits individually and in combination. If no bits are set in this field - i.e., it contains the value .Em LTM_NONE - then the entire period is assumed invalid. This is used as a convention to mark the termination of an array of login_time_t values. If .Fn parse_lt returns a .Ar login_time_t with .Ar lt_dow equal to .Em LTM_NONE then a parsing error was encountered. .Pp The remaining functions provide the ability to test a given time_t or struct tm value against a specific time period or array of time periods. The .Fn in_ltm function determines whether the given time described by the struct tm passed as the second parameter falls within the period described by the first parameter. A boolean value is returned, indicating whether or not the time specified falls within the period. If the time does fall within the time period, and the third parameter to the function is not NULL, the time at which the period ends relative to the time passed is returned. .Pp The .Fn in_ltms function is similar to .Fn in_ltm except that the first parameter must be a pointer to an array of login_time_t objects, which is up to LC_MAXTIMES (64) elements in length, and terminated by an element with its .Ar lt_dow field set to .Em LTM_NONE . .Pp The .Fn in_lt and .Fn in_lts functions are equivalent to .Fn in_ltm and .Fn in_ltms , respectively, with the second argument set to the current time as returned by .Xr localtime 3 . .Sh RETURN VALUES The .Fn parse_lt function returns a filled in structure of type login_time_t containing the parsed time period. If a parsing error occurs, the lt_dow field is set to .Em LTM_NONE (i.e., 0). .Pp The .Fn in_ltm function returns non-zero if the given time falls within the period described by the login_time_t passed as the first parameter. .Pp The .Fn in_ltms function returns the index of the first time period found in which the given time falls, or -1 if none of them apply. .Sh SEE ALSO .Xr getcap 3 , .Xr login_cap 3 , .Xr login_class 3 , .Xr login.conf 5 , .Xr termcap 5 freebsd-libs-10.1~svn273304/lib/libutil/property.c0000644000000000000000000001345510342630230016535 0ustar /* * * Simple property list handling code. * * Copyright (c) 1998 * Jordan Hubbard. 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, * verbatim and that no modifications are made prior to this * point in the file. * 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 ``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 HIS PETS 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, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include static properties property_alloc(char *name, char *value) { properties n; if ((n = (properties)malloc(sizeof(struct _property))) == NULL) return (NULL); n->next = NULL; if (name != NULL) { if ((n->name = strdup(name)) == NULL) { free(n); return (NULL); } } else n->name = NULL; if (value != NULL) { if ((n->value = strdup(value)) == NULL) { free(n->name); free(n); return (NULL); } } else n->value = NULL; return (n); } properties properties_read(int fd) { properties head, ptr; char hold_n[PROPERTY_MAX_NAME + 1]; char hold_v[PROPERTY_MAX_VALUE + 1]; char buf[BUFSIZ * 4]; int bp, n, v, max; enum { LOOK, COMMENT, NAME, VALUE, MVALUE, COMMIT, FILL, STOP } state, last_state; int ch = 0, blevel = 0; n = v = bp = max = 0; head = ptr = NULL; state = last_state = LOOK; while (state != STOP) { if (state != COMMIT) { if (bp == max) { last_state = state; state = FILL; } else ch = buf[bp++]; } switch(state) { case FILL: if ((max = read(fd, buf, sizeof buf)) < 0) { properties_free(head); return (NULL); } if (max == 0) { state = STOP; } else { /* * Restore the state from before the fill (which will be * initialised to LOOK for the first FILL). This ensures that * if we were part-way through eg., a VALUE state, when the * buffer ran out, that the previous operation will be allowed * to complete. */ state = last_state; ch = buf[0]; bp = 0; } continue; case LOOK: if (isspace((unsigned char)ch)) continue; /* Allow shell or lisp style comments */ else if (ch == '#' || ch == ';') { state = COMMENT; continue; } else if (isalnum((unsigned char)ch) || ch == '_') { if (n >= PROPERTY_MAX_NAME) { n = 0; state = COMMENT; } else { hold_n[n++] = ch; state = NAME; } } else state = COMMENT; /* Ignore the rest of the line */ break; case COMMENT: if (ch == '\n') state = LOOK; break; case NAME: if (ch == '\n' || !ch) { hold_n[n] = '\0'; hold_v[0] = '\0'; v = n = 0; state = COMMIT; } else if (isspace((unsigned char)ch)) continue; else if (ch == '=') { hold_n[n] = '\0'; v = n = 0; state = VALUE; } else hold_n[n++] = ch; break; case VALUE: if (v == 0 && ch == '\n') { hold_v[v] = '\0'; v = n = 0; state = COMMIT; } else if (v == 0 && isspace((unsigned char)ch)) continue; else if (ch == '{') { state = MVALUE; ++blevel; } else if (ch == '\n' || !ch) { hold_v[v] = '\0'; v = n = 0; state = COMMIT; } else { if (v >= PROPERTY_MAX_VALUE) { state = COMMENT; v = n = 0; break; } else hold_v[v++] = ch; } break; case MVALUE: /* multiline value */ if (v >= PROPERTY_MAX_VALUE) { warn("properties_read: value exceeds max length"); state = COMMENT; n = v = 0; } else if (ch == '}' && !--blevel) { hold_v[v] = '\0'; v = n = 0; state = COMMIT; } else { hold_v[v++] = ch; if (ch == '{') ++blevel; } break; case COMMIT: if (head == NULL) { if ((head = ptr = property_alloc(hold_n, hold_v)) == NULL) return (NULL); } else { if ((ptr->next = property_alloc(hold_n, hold_v)) == NULL) { properties_free(head); return (NULL); } ptr = ptr->next; } state = LOOK; v = n = 0; break; case STOP: /* we don't handle this here, but this prevents warnings */ break; } } if (head == NULL && (head = property_alloc(NULL, NULL)) == NULL) return (NULL); return (head); } char * property_find(properties list, const char *name) { if (list == NULL || name == NULL || !name[0]) return (NULL); while (list != NULL) { if (list->name != NULL && strcmp(list->name, name) == 0) return (list->value); list = list->next; } return (NULL); } void properties_free(properties list) { properties tmp; while (list) { tmp = list->next; if (list->name) free(list->name); if (list->value) free(list->value); free(list); list = tmp; } } freebsd-libs-10.1~svn273304/lib/libutil/login_times.c0000644000000000000000000000733612163601320017164 0ustar /*- * Copyright (c) 1996 by * David Nugent * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * 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. * 3. This work was done expressly for inclusion into FreeBSD. Other use * is permitted provided this notation is included. * 4. Absolutely no warranty of function or purpose is made by the authors. * 5. Modifications may be freely made to this file providing the above * conditions are met. * * Login period parsing and comparison functions. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include static struct { const char *dw; u_char cn; u_char fl; } dws[] = { { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } }; static char * parse_time(char * ptr, u_short * t) { u_short val; for (val = 0; *ptr && isdigit(*ptr); ptr++) val = (u_short)(val * 10 + (*ptr - '0')); *t = (u_short)((val / 100) * 60 + (val % 100)); return (ptr); } login_time_t parse_lt(const char *str) { login_time_t t; memset(&t, 0, sizeof t); t.lt_dow = LTM_NONE; if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) { int i; login_time_t m = t; char *p; char buf[64]; /* Make local copy and force lowercase to simplify parsing */ strlcpy(buf, str, sizeof buf); for (i = 0; buf[i]; i++) buf[i] = (char)tolower(buf[i]); p = buf; while (isalpha(*p)) { i = 0; while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0) i++; if (dws[i].dw == NULL) break; m.lt_dow |= dws[i].fl; p += dws[i].cn; } if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ m.lt_dow |= LTM_ANY; if (isdigit(*p)) p = parse_time(p, &m.lt_start); else m.lt_start = 0; if (*p == '-') p = parse_time(p + 1, &m.lt_end); else m.lt_end = 1440; t = m; } return (t); } int in_ltm(const login_time_t *ltm, struct tm *tt, time_t *ends) { int rc = 0; if (tt != NULL) { /* First, examine the day of the week */ if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) { /* Convert `current' time to minute of the day */ u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); if (tt->tm_sec > 30) ++now; if (now >= ltm->lt_start && now < ltm->lt_end) { rc = 2; if (ends != NULL) { /* If requested, return ending time for this period */ tt->tm_hour = (int)(ltm->lt_end / 60); tt->tm_min = (int)(ltm->lt_end % 60); *ends = mktime(tt); } } } } return (rc); } int in_lt(const login_time_t *ltm, time_t *t) { return (in_ltm(ltm, localtime(t), t)); } int in_ltms(const login_time_t *ltm, struct tm *tm, time_t *t) { int i = 0; while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) { if (in_ltm(ltm + i, tm, t)) return (i); i++; } return (-1); } int in_lts(const login_time_t *ltm, time_t *t) { return (in_ltms(ltm, localtime(t), t)); } freebsd-libs-10.1~svn273304/lib/libutil/kinfo_getallproc.c0000644000000000000000000000515311562731133020200 0ustar /*- * Copyright (c) 2007 Robert N. M. Watson * Copyright (c) 2009 Ulf Lilleengen * 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "libutil.h" /* * Sort processes first by pid and then tid. */ static int kinfo_proc_compare(const void *a, const void *b) { int i; i = ((const struct kinfo_proc *)a)->ki_pid - ((const struct kinfo_proc *)b)->ki_pid; if (i != 0) return (i); i = ((const struct kinfo_proc *)a)->ki_tid - ((const struct kinfo_proc *)b)->ki_tid; return (i); } static void kinfo_proc_sort(struct kinfo_proc *kipp, int count) { qsort(kipp, count, sizeof(*kipp), kinfo_proc_compare); } struct kinfo_proc * kinfo_getallproc(int *cntp) { struct kinfo_proc *kipp; size_t len; int mib[3]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PROC; len = 0; if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) return (NULL); kipp = malloc(len); if (kipp == NULL) return (NULL); if (sysctl(mib, 3, kipp, &len, NULL, 0) < 0) goto bad; if (len % sizeof(*kipp) != 0) goto bad; if (kipp->ki_structsize != sizeof(*kipp)) goto bad; *cntp = len / sizeof(*kipp); kinfo_proc_sort(kipp, len / sizeof(*kipp)); return (kipp); bad: *cntp = 0; free(kipp); return (NULL); } freebsd-libs-10.1~svn273304/lib/libutil/login_ok.30000644000000000000000000001024311361411226016366 0ustar .\" Copyright (c) 1995 David Nugent .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, is permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice immediately at the beginning of the file, without modification, .\" 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. .\" 3. This work was done expressly for inclusion into FreeBSD. Other use .\" is permitted provided this notation is included. .\" 4. Absolutely no warranty of function or purpose is made by the author .\" David Nugent. .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" .\" $FreeBSD$ .\" .Dd January 2, 1997 .Dt LOGIN_OK 3 .Os .Sh NAME .Nm auth_ttyok , .Nm auth_hostok , .Nm auth_timeok .Nd functions for checking login class based login restrictions .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In time.h .In login_cap.h .Ft int .Fn auth_ttyok "login_cap_t *lc" "const char *tty" .Ft int .Fn auth_hostok "login_cap_t *lc" "const char *host" "char const *ip" .Ft int .Fn auth_timeok "login_cap_t *lc" "time_t t" .Sh DESCRIPTION This set of functions checks to see if login is allowed based on login class capability entries in the login database, .Xr login.conf 5 . .Pp The .Fn auth_ttyok function checks to see if the named tty is available to users of a specific class, and is either in the .Em ttys.allow access list, and not in the .Em ttys.deny access list. An empty .Em ttys.allow list (or if no such capability exists for the given login class) logins via any tty device are allowed unless the .Em ttys.deny list exists and is non-empty, and the device or its tty group (see .Xr ttys 5 ) is not in the list. Access to ttys may be allowed or restricted specifically by tty device name, a device name which includes a wildcard (e.g.\& ttyD* or cuaD*), or may name a ttygroup, when group= tags have been assigned in .Pa /etc/ttys . Matching of ttys and ttygroups is case sensitive. Passing a .Dv NULL or empty string as the .Ar tty parameter causes the function to return a non-zero value. .Pp The .Fn auth_hostok function checks for any host restrictions for remote logins. The function checks on both a host name and IP address (given in its text form, typically n.n.n.n) against the .Em host.allow and .Em host.deny login class capabilities. As with ttys and their groups, wildcards and character classes may be used in the host allow and deny capability records. The .Xr fnmatch 3 function is used for matching, and the matching on hostnames is case insensitive. Note that this function expects that the hostname is fully expanded (i.e., the local domain name added if necessary) and the IP address is in its canonical form. No hostname or address lookups are attempted. .Pp It is possible to call this function with either the hostname or the IP address missing (i.e.\& .Dv NULL ) and matching will be performed only on the basis of the parameter given. Passing .Dv NULL or empty strings in both parameters will result in a non-zero return value. .Pp The .Fn auth_timeok function checks to see that a given time value is within the .Em times.allow login class capability and not within the .Em times.deny access lists. An empty or non-existent .Em times.allow list allows access at any time, except if a given time is falls within a period in the .Em times.deny list. The format of time period records contained in both .Em times.allow and .Em times.deny capability fields is explained in detail in the .Xr login_times 3 manual page. .Sh RETURN VALUES A non-zero return value from any of these functions indicates that login access is granted. A zero return value means either that the item being tested is not in the .Em allow access list, or is within the .Em deny access list. .Sh SEE ALSO .Xr getcap 3 , .Xr login_cap 3 , .Xr login_class 3 , .Xr login_times 3 , .Xr login.conf 5 , .Xr termcap 5 freebsd-libs-10.1~svn273304/lib/libutil/login_auth.c0000644000000000000000000000601112207463515017004 0ustar /*- * Copyright (c) 1996 by * Sean Eric Fagan * David Nugent * All rights reserved. * * Portions copyright (c) 1995,1997 by * Berkeley Software Design, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * 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. * 3. This work was done expressly for inclusion into FreeBSD. Other use * is permitted provided this notation is included. * 4. Absolutely no warranty of function or purpose is made by the authors. * 5. Modifications may be freely made to this file providing the above * conditions are met. * * Low-level routines relating to the user capabilities database */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * auth_checknologin() * Checks for the existance of a nologin file in the login_cap * capability . If there isn't one specified, then it checks * to see if this class should just ignore nologin files. Lastly, * it tries to print out the default nologin file, and, if such * exists, it exits. */ void auth_checknologin(login_cap_t *lc) { const char *file; /* Do we ignore a nologin file? */ if (login_getcapbool(lc, "ignorenologin", 0)) return; /* Note that will be "" if there is no nologin capability */ if ((file = login_getcapstr(lc, "nologin", "", NULL)) == NULL) exit(1); /* * *file is true IFF there was a "nologin" capability * Note that auth_cat() returns 1 only if the specified * file exists, and is readable. E.g., /.nologin exists. */ if ((*file && auth_cat(file)) || auth_cat(_PATH_NOLOGIN)) exit(1); } /* * auth_cat() * Checks for the readability of ; if it can be opened for * reading, it prints it out to stdout, and then exits. Otherwise, * it returns 0 (meaning no nologin file). */ int auth_cat(const char *file) { int fd, count; char buf[BUFSIZ]; if ((fd = open(file, O_RDONLY | O_CLOEXEC)) < 0) return 0; while ((count = read(fd, buf, sizeof(buf))) > 0) (void)write(fileno(stdout), buf, count); close(fd); sleep(5); /* wait an arbitrary time to drain */ return 1; } freebsd-libs-10.1~svn273304/lib/libutil/_secure_path.c0000644000000000000000000000452110161021420017276 0ustar /*- * Based on code copyright (c) 1995,1997 by * Berkeley Software Design, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * 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. * 3. This work was done expressly for inclusion into FreeBSD. Other use * is permitted provided this notation is included. * 4. Absolutely no warranty of function or purpose is made by the authors. * 5. Modifications may be freely made to this file providing the above * conditions are met. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include /* * Check for common security problems on a given path * It must be: * 1. A regular file, and exists * 2. Owned and writable only by root (or given owner) * 3. Group ownership is given group or is non-group writable * * Returns: -2 if file does not exist, * -1 if security test failure * 0 otherwise */ int _secure_path(const char *path, uid_t uid, gid_t gid) { int r = -1; struct stat sb; const char *msg = NULL; if (lstat(path, &sb) < 0) { if (errno == ENOENT) /* special case */ r = -2; /* if it is just missing, skip the log entry */ else msg = "%s: cannot stat %s: %m"; } else if (!S_ISREG(sb.st_mode)) msg = "%s: %s is not a regular file"; else if (sb.st_mode & S_IWOTH) msg = "%s: %s is world writable"; else if ((int)uid != -1 && sb.st_uid != uid && sb.st_uid != 0) { if (uid == 0) msg = "%s: %s is not owned by root"; else msg = "%s: %s is not owned by uid %d"; } else if ((int)gid != -1 && sb.st_gid != gid && (sb.st_mode & S_IWGRP)) msg = "%s: %s is group writeable by non-authorised groups"; else r = 0; if (msg != NULL) syslog(LOG_ERR, msg, "_secure_path", path, uid); return r; } freebsd-libs-10.1~svn273304/lib/libutil/login_cap.30000644000000000000000000003731611734766324016552 0ustar .\" Copyright (c) 1995 David Nugent .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, is permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice immediately at the beginning of the file, without modification, .\" 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. .\" 3. This work was done expressly for inclusion into FreeBSD. Other use .\" is permitted provided this notation is included. .\" 4. Absolutely no warranty of function or purpose is made by the author .\" David Nugent. .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" .\" $FreeBSD$ .\" .Dd June 14, 2007 .Dt LOGIN_CAP 3 .Os .Sh NAME .Nm login_close , .Nm login_getcapbool , .Nm login_getcaplist , .Nm login_getcapnum , .Nm login_getcapstr , .Nm login_getcapsize , .Nm login_getcaptime , .Nm login_getclass , .Nm login_getclassbyname , .Nm login_getpwclass , .Nm login_getstyle , .Nm login_getuserclass , .Nm login_setcryptfmt .Nd "functions for accessing the login class capabilities database" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In login_cap.h .Ft void .Fn login_close "login_cap_t *lc" .Ft login_cap_t * .Fn login_getclassbyname "const char *nam" "const struct passwd *pwd" .Ft login_cap_t * .Fn login_getclass "const char *nam" .Ft login_cap_t * .Fn login_getpwclass "const struct passwd *pwd" .Ft login_cap_t * .Fn login_getuserclass "const struct passwd *pwd" .Ft "const char *" .Fn login_getcapstr "login_cap_t *lc" "const char *cap" "const char *def" "const char *error" .Ft "const char **" .Fn login_getcaplist "login_cap_t *lc" "const char *cap" "const char *chars" .Ft "const char *" .Fn login_getpath "login_cap_t *lc" "const char *cap" "const char *error" .Ft rlim_t .Fn login_getcaptime "login_cap_t *lc" "const char *cap" "rlim_t def" "rlim_t error" .Ft rlim_t .Fn login_getcapnum "login_cap_t *lc" "const char *cap" "rlim_t def" "rlim_t error" .Ft rlim_t .Fn login_getcapsize "login_cap_t *lc" "const char *cap" "rlim_t def" "rlim_t error" .Ft int .Fn login_getcapbool "login_cap_t *lc" "const char *cap" "int def" .Ft "const char *" .Fn login_getstyle "login_cap_t *lc" "const char *style" "const char *auth" .Ft const char * .Fn login_setcryptfmt "login_cap_t *lc" "const char *def" "const char *error" .Sh DESCRIPTION These functions represent a programming interface to the login classes database provided in .Xr login.conf 5 . This database contains capabilities, attributes and default environment and accounting settings for users and programs running as specific users, as determined by the login class field within entries in .Pa /etc/master.passwd . .Pp Entries in .Xr login.conf 5 consist of colon .Ql \&: separated fields, the first field in each record being one or more identifiers for the record (which must be unique for the entire database), each separated by a .Ql | , and may optionally include a description as the last .Sq name . Remaining fields in the record consist of keyword/data pairs. Long lines may be continued with a backslash within empty entries, with the second and subsequent lines optionally indented for readability. This is similar to the format used in .Xr termcap 5 , except that keywords are not limited to two significant characters, and are usually longer for improved readability. As with termcap entries, multiple records can be linked together (one record including another) using a field containing .Ql tc= Ns Va . The result is that the entire record referenced by .Va replaces the .Va tc= field at the point at which it occurs. See .Xr getcap 3 for further details on the format and use of a capabilities database. .Pp The .Nm login_cap interface provides a convenient means of retrieving login class records with all .Va tc= references expanded. A program will typically call one of .Fn login_getclass , .Fn login_getpwclass , .Fn login_getuserclass or .Fn login_getclassbyname according to its requirements. Each of these functions returns a login capabilities structure, .Vt login_cap_t , which may subsequently be used to interrogate the database for specific values using the rest of the API. Once the .Vt login_cap_t is of no further use, the .Fn login_close function should be called to free all resources used. .Pp The structure of .Vt login_cap_t is defined in .In login_cap.h , as: .Bd -literal -offset indent typedef struct { char *lc_class; char *lc_cap; char *lc_style; } login_cap_t; .Ed .Pp The .Fa lc_class member contains a pointer to the name of the login class retrieved. This may not necessarily be the same as the one requested, either directly via .Fn login_getclassbyname , or indirectly via a user's login record using .Fn login_getpwclass , by class name using .Fn login_getclass . If the referenced user has no login class specified in .Pa /etc/master.passwd , the class name is .Dv NULL or an empty string. If the class specified does not exist in the database, each of these functions will search for a record with an id of .Ql default , with that name returned in the .Fa lc_class field. In addition, if the referenced user has a UID of 0 (normally, .Ql root , although the user name is not considered) then .Fn login_getpwclass will search for a record with an id of .Ql root before it searches for the record with the id of .Ql default . .Pp The .Fa lc_cap field is used internally by the library to contain the expanded login capabilities record. Programs with unusual requirements may wish to use this with the lower-level .Fn getcap style functions to access the record directly. .Pp The .Fa lc_style field is set by the .Fn login_getstyle function to the authorisation style, according to the requirements of the program handling a login itself. .Pp The .Fn login_getclassbyname function is the basic means to get a .Vt login_cap_t object. It accepts two arguments: the first one, .Fa name , is the record identifier of the record to be retrieved; the second, .Fa pwd , is an optional pointer to a .Vt passwd structure. First of all, its arguments are used by the function to choose between system and user modes of operation. When in system mode, only the system login class database is used. When in user mode, the supplemental login class database in the user's home directory is allowed to override settings from the system database in a limited way as noted below. To minimize security implications, user mode is entered by .Fn login_getclassbyname if and only if .Fa name is .Dv LOGIN_MECLASS .Pq Ql me and .Fa pwd is not .Dv NULL . Otherwise system mode is chosen. .Pp In system mode, any record in the system database .Pa /etc/login.conf can be accessed, and a fallback to the default record is provided as follows. If .Fa name is .Dv NULL , an empty string, or a class that does not exist in the login class database, then the .Dv LOGIN_DEFCLASS record .Pq Ql default is returned instead. .Pp In user mode, only the .Dv LOGIN_MECLASS record .Pq Ql me is accessed and no fallback to the .Ql default record is provided. The directory specified by .Fa pwd->pw_dir is searched for a login database file called .Pa .login_conf , and only the .Ql me capability record contained within it may override the system record with the same name while other records are ignored. Using this scheme, an application can explicitly allow users to override a selected subset of login settings. To do so, the application should obtain two .Vt login_cap_t objects, one in user mode and the other in system mode, and then query the user object before the system object for login parameters that are allowed to be overridden by the user. For example, the user's .Pa .login_conf can provide a convenient way for a user to set up their preferred login environment before the shell is invoked on login if supported by .Xr login 1 . .Pp Note that access to the .Pa /etc/login.conf and .Pa .login_conf files will only be performed subject to the security checks documented in .Xr _secure_path 3 for the uids 0 and .Fa pwd->pw_uid respectively. .Pp If the specified record is .Dv NULL , empty or does not exist, and the system has no .Ql default record available to fall back to, there is a memory allocation error or for some reason .Xr cgetent 3 is unable to access the login capabilities database, this function returns .Dv NULL . .Pp The functions .Fn login_getclass , .Fn login_getpwclass and .Fn login_getuserclass retrieve the applicable login class record for the user's passwd entry or class name by calling .Fn login_getclassbyname . On failure, .Dv NULL is returned. The difference between these functions is that .Fn login_getuserclass includes the user's overriding .Pa .login_conf that exists in the user's home directory, and .Fn login_getpwclass and .Fn login_getclass restrict lookup only to the system login class database in .Pa /etc/login.conf . As explained earlier, .Fn login_getpwclass differs from .Fn login_getclass in that it allows the default class for a super-user as .Ql root if none has been specified in the password database. Otherwise, if the passwd pointer is .Dv NULL , or the user record has no login class, then the system .Ql default entry is retrieved. Essentially, .Fn login_getclass name is equivalent to .Fn login_getclassbyname name NULL and .Fn login_getuserclass pwd to .Fn login_getclassbyname LOGIN_MECLASS pwd . .Pp Once a program no longer wishes to use a .Vt login_cap_t object, .Fn login_close may be called to free all resources used by the login class. The .Fn login_close function may be passed a .Dv NULL pointer with no harmful side-effects. .Pp The remaining functions may be used to retrieve individual capability records. Each function takes a .Vt login_cap_t object as its first parameter, a capability tag as the second, and remaining parameters being default and error values that are returned if the capability is not found. The type of the additional parameters passed and returned depend on the .Em type of capability each deals with, be it a simple string, a list, a time value, a file or memory size value, a path (consisting of a colon-separated list of directories) or a boolean flag. The manpage for .Xr login.conf 5 deals in specific tags and their type. .Pp Note that with all functions in this group, you should not call .Xr free 3 on any pointers returned. Memory allocated during retrieval or processing of capability tags is automatically reused by subsequent calls to functions in this group, or deallocated on calling .Fn login_close . .Bl -tag -width "login_getcaplist()" .It Fn login_getcapstr This function returns a simple string capability. If the string is not found, then the value in .Fa def is returned as the default value, or if an error occurs, the value in the .Fa error parameter is returned. .It Fn login_getcaplist This function returns the value corresponding to the named capability tag as a list of values in a .Dv NULL terminated array. Within the login class database, some tags are of type .Vt list , which consist of one or more comma- or space separated values. Usually, this function is not called directly from an application, but is used indirectly via .Fn login_getstyle . .It Fn login_getpath This function returns a list of directories separated by colons .Ql \&: . Capability tags for which this function is called consist of a list of directories separated by spaces. .It Fn login_getcaptime This function returns a .Vt time value associated with a particular capability tag with the value expressed in seconds (the default), minutes, hours, days, weeks or (365 day) years or any combination of these. A suffix determines the units used: .Ql S for seconds, .Ql M for minutes, .Ql H for hours, .Ql D for days, .Ql W for weeks and .Ql Y for 365 day years. Case of the units suffix is ignored. .Pp Time values are normally used for setting resource, accounting and session limits. If supported by the operating system and compiler (which is true of .Fx ) , the value returned is a .Vt quad .Pq Vt long long , of type .Vt rlim_t . A value .Ql inf or .Ql infinity may be used to express an infinite value, in which case .Dv RLIM_INFINITY is returned. .It Fn login_getcapnum This function returns a numeric value for a tag, expressed either as .Ql tag= or the standard .Fn cgetnum format .Ql tag# . The first format should be used in preference to the second, the second format is provided for compatibility and consistency with the .Xr getcap 3 database format where numeric types use the .Ql \&# as the delimiter for numeric values. If in the first format, then the value given may be .Ql inf or .Ql infinity which results in a return value of .Dv RLIM_INFINITY . If the given capability tag cannot be found, the .Fa def parameter is returned, and if an error occurs, the .Fa error parameter is returned. .It Fn login_getcapsize .Fn login_getcapsize returns a value representing a size (typically, file or memory) which may be expressed as bytes (the default), 512 byte blocks, kilobytes, megabytes, gigabytes, and on systems that support the .Vt long long type, terabytes. The suffix used determines the units, and multiple values and units may be used in combination (e.g.\& 1m500k = 1.5 megabytes). A value with no suffix is interpreted as bytes, .Ql B as 512-byte blocks, .Ql K as kilobytes, .Ql M as megabytes, .Ql G as gigabytes and .Ql T as terabytes. Case is ignored. The error value is returned if there is a login capabilities database error, if an invalid suffix is used, or if a numeric value cannot be interpreted. .It Fn login_getcapbool This function returns a boolean value tied to a particular flag. It returns 0 if the given capability tag is not present or is negated by the presence of a .Ql tag@ (see .Xr getcap 3 for more information on boolean flags), and returns 1 if the tag is found. .It Fn login_getstyle This function is used by the login authorisation system to determine the style of login available in a particular case. The function accepts three parameters, the .Fa lc entry itself and two optional parameters, and authorisation type .Fa auth and .Fa style , and applies these to determine the authorisation style that best suites these rules. .Bl -bullet .It If .Fa auth is neither .Dv NULL nor an empty string, look for a tag of type .Ql auth- Ns Fa in the capability record. If not present, then look for the default tag .Va auth= . .It If no valid authorisation list was found from the previous step, then default to .Ql passwd as the authorisation list. .It If .Fa style is not .Dv NULL or empty, look for it in the list of authorisation methods found from the previous step. If .Fa style is .Dv NULL or an empty string, then default to .Ql passwd authorisation. .It If .Fa style is found in the chosen list of authorisation methods, then return that, otherwise return .Dv NULL . .El .Pp This scheme allows the administrator to determine the types of authorisation methods accepted by the system, depending on the means by which the access occurs. For example, the administrator may require skey or kerberos as the authentication method used for access to the system via the network, and standard methods via direct dialup or console logins, significantly reducing the risk of password discovery by "snooping" network packets. .It Fn login_setcryptfmt The .Fn login_setcryptfmt function is used to set the .Xr crypt 3 format using the .Va passwd_format configuration entry. If no entry is found, .Fa def is taken to be used as the fallback. If calling .Xr crypt_set_format 3 on the specifier fails, .Fa error is returned to indicate this. .El .Sh SEE ALSO .Xr login 1 , .Xr crypt 3 , .Xr getcap 3 , .Xr login_class 3 , .Xr login.conf 5 , .Xr termcap 5 freebsd-libs-10.1~svn273304/lib/libutil/realhostname_sa.30000644000000000000000000001110011453610460017726 0ustar .\" Copyright (C) 1995, 1996, 1997, 1998, 1999, and 2000 WIDE Project. .\" 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. .\" 3. Neither the name of the project nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. .\" .\" Copyright (c) 1999 Brian Somers .\" 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. .\" .\" $FreeBSD$ .\" .Dd January 11, 2000 .Dt REALHOSTNAME_SA 3 .Os .Sh NAME .Nm realhostname_sa .Nd "convert a" .Vt "struct sockaddr" to the real host name .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In netinet/in.h .In libutil.h .Ft int .Fn realhostname_sa "char *host" "size_t hsize" "struct sockaddr *addr" "int addrlen" .Sh DESCRIPTION The function .Fn realhostname_sa converts .Ar addr to the corresponding host name. This is done by resolving .Ar addr to a host name and then ensuring that the host name resolves back to .Ar addr . .Pp .Ar host must point to a buffer of at least .Ar hsize bytes, and will always be written to by this function. .Pp If the name resolution does not work both ways or if the host name is longer than .Ar hsize bytes, .Xr getnameinfo 3 with NI_NUMERICHOST specified, is used to convert .Ar addr to an ASCII form. .Pp If the string written to .Ar host is .Ar hsize bytes long, .Ar host will not be NUL terminated. .Sh RETURN VALUES The .Fn realhostname_sa function will return one of the following constants which are defined in .In libutil.h : .Bl -tag -width XXX -offset XXX .It Li HOSTNAME_FOUND A valid host name was found. .It Li HOSTNAME_INCORRECTNAME A host name was found, but it did not resolve back to the passed .Ar ip . .Ar host now contains the numeric value of .Ar ip . .It Li HOSTNAME_INVALIDADDR .Ar ip could not be resolved. .Ar host now contains the numeric value of .Ar ip . .It Li HOSTNAME_INVALIDNAME A host name was found, but it could not be resolved back to any ip number. .Ar host now contains the numeric value of .Ar ip . .El .Sh SEE ALSO .Xr getaddrinfo 3 , .Xr getnameinfo 3 , .Xr realhostname 3 freebsd-libs-10.1~svn273304/lib/libutil/login_auth.30000644000000000000000000000433111361411226016717 0ustar .\" Copyright (c) 1995 David Nugent .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, is permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice immediately at the beginning of the file, without modification, .\" 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. .\" 3. This work was done expressly for inclusion into FreeBSD. Other use .\" is permitted provided this notation is included. .\" 4. Absolutely no warranty of function or purpose is made by the author .\" David Nugent. .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" .\" $FreeBSD$ .\" .Dd December 29, 1996 .Dt LOGIN_AUTH 3 .Os .Sh NAME .\" .Nm authenticate .\" .Nm auth_script .\" .Nm auth_env .\" .Nm auth_scan .\" .Nm auth_rmfiles .Nm auth_checknologin , .Nm auth_cat .\" .Nm auth_ttyok .\" .Nm auth_hostok .\" .Nm auth_timesok .Nd "authentication style support library for login class capabilities database" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In login_cap.h .\" .Ft int .\". Fn authenticate "const char *name" "const char *classname" "const char *style" "const char *service" .\" .Ft int .\" .Fn auth_script "const char * path" ... .\" .Ft void .\" .Fn auth_env "void" .\" .Ft int .\" .Fn auth_scan "int ok" .\" .Ft void .\" .Fn auth_rmfiles "void" .Ft void .Fn auth_checknologin "login_cap_t *lc" .Ft int .Fn auth_cat "const char *file" .\" .Ft int .\" .Fn auth_ttyok "login_cap_t *lc" "const char *tty" .\" .Ft int .\" .Fn auth_hostok "login_cap_t *lc" "const char *hostname" "char const *ip" .\" .Ft int .\" .Fn auth_timesok "login_cap_t *lc" "time_t now" .Sh DESCRIPTION This set of functions support the login class authorisation style interface provided by .Xr login.conf 5 . .\" .Sh RETURN VALUES .Sh SEE ALSO .Xr getcap 3 , .Xr login_cap 3 , .Xr login_class 3 , .Xr login.conf 5 , .Xr termcap 5 freebsd-libs-10.1~svn273304/lib/libutil/_secure_path.30000644000000000000000000000473011361411226017232 0ustar .\" Copyright (c) 1997 David Nugent .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, is permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice immediately at the beginning of the file, without modification, .\" 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. .\" 3. This work was done expressly for inclusion into FreeBSD. Other use .\" is permitted provided this notation is included. .\" 4. Absolutely no warranty of function or purpose is made by the author .\" David Nugent. .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" .\" $FreeBSD$ .\" .Dd May 2, 1997 .Dt _SECURE_PATH 3 .Os .Sh NAME .Nm _secure_path .Nd determine if a file appears to be secure .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft int .Fn _secure_path "const char *path" "uid_t uid" "gid_t gid" .Sh DESCRIPTION This function does some basic security checking on a given path. It is intended to be used by processes running with root privileges in order to decide whether or not to trust the contents of a given file. It uses a method often used to detect system compromise. .Pp A file is considered .Sq secure if it meets the following conditions: .Bl -enum .It The file exists, and is a regular file (not a symlink, device special or named pipe, etc.), .It Is not world writable. .It Is owned by the given uid or uid 0, if uid is not -1, .It Is not group writable or it has group ownership by the given gid, if gid is not -1. .El .Sh RETURN VALUES This function returns zero if the file exists and may be considered secure, -2 if the file does not exist, and -1 otherwise to indicate a security failure. The .Xr syslog 3 function is used to log any failure of this function, including the reason, at LOG_ERR priority. .Sh SEE ALSO .Xr lstat 2 , .Xr syslog 3 .Sh HISTORY Code from which this function was derived was contributed to the .Fx project by Berkeley Software Design, Inc. .Sh BUGS The checks carried out are rudimentary and no attempt is made to eliminate race conditions between use of this function and access to the file referenced. freebsd-libs-10.1~svn273304/lib/libutil/login_cap.c0000644000000000000000000004633412207463515016622 0ustar /*- * Copyright (c) 1996 by * Sean Eric Fagan * David Nugent * All rights reserved. * * Portions copyright (c) 1995,1997 * Berkeley Software Design, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * 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. * 3. This work was done expressly for inclusion into FreeBSD. Other use * is permitted provided this notation is included. * 4. Absolutely no warranty of function or purpose is made by the authors. * 5. Modifications may be freely made to this file providing the above * conditions are met. * * Low-level routines relating to the user capabilities database */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * allocstr() * Manage a single static pointer for handling a local char* buffer, * resizing as necessary to contain the string. * * allocarray() * Manage a static array for handling a group of strings, resizing * when necessary. */ static int lc_object_count = 0; static size_t internal_stringsz = 0; static char * internal_string = NULL; static size_t internal_arraysz = 0; static const char ** internal_array = NULL; static char path_login_conf[] = _PATH_LOGIN_CONF; static char * allocstr(const char *str) { char *p; size_t sz = strlen(str) + 1; /* realloc() only if necessary */ if (sz <= internal_stringsz) p = strcpy(internal_string, str); else if ((p = realloc(internal_string, sz)) != NULL) { internal_stringsz = sz; internal_string = strcpy(p, str); } return p; } static const char ** allocarray(size_t sz) { static const char **p; if (sz <= internal_arraysz) p = internal_array; else if ((p = realloc(internal_array, sz * sizeof(char*))) != NULL) { internal_arraysz = sz; internal_array = p; } return p; } /* * arrayize() * Turn a simple string separated by any of * the set of into an array. The last element * of the array will be NULL, as is proper. * Free using freearraystr() */ static const char ** arrayize(const char *str, const char *chars, int *size) { int i; char *ptr; const char *cptr; const char **res = NULL; /* count the sub-strings */ for (i = 0, cptr = str; *cptr; i++) { int count = strcspn(cptr, chars); cptr += count; if (*cptr) ++cptr; } /* alloc the array */ if ((ptr = allocstr(str)) != NULL) { if ((res = allocarray(++i)) == NULL) free((void *)(uintptr_t)(const void *)str); else { /* now split the string */ i = 0; while (*ptr) { int count = strcspn(ptr, chars); res[i++] = ptr; ptr += count; if (*ptr) *ptr++ = '\0'; } res[i] = NULL; } } if (size) *size = i; return res; } /* * login_close() * Frees up all resources relating to a login class * */ void login_close(login_cap_t * lc) { if (lc) { free(lc->lc_style); free(lc->lc_class); free(lc->lc_cap); free(lc); if (--lc_object_count == 0) { free(internal_string); free(internal_array); internal_array = NULL; internal_arraysz = 0; internal_string = NULL; internal_stringsz = 0; cgetclose(); } } } /* * login_getclassbyname() * Get the login class by its name. * If the name given is NULL or empty, the default class * LOGIN_DEFCLASS (i.e., "default") is fetched. * If the name given is LOGIN_MECLASS and * 'pwd' argument is non-NULL and contains an non-NULL * dir entry, then the file _FILE_LOGIN_CONF is picked * up from that directory and used before the system * login database. In that case the system login database * is looked up using LOGIN_MECLASS, too, which is a bug. * Return a filled-out login_cap_t structure, including * class name, and the capability record buffer. */ login_cap_t * login_getclassbyname(char const *name, const struct passwd *pwd) { login_cap_t *lc; if ((lc = malloc(sizeof(login_cap_t))) != NULL) { int r, me, i = 0; uid_t euid = 0; gid_t egid = 0; const char *msg = NULL; const char *dir; char userpath[MAXPATHLEN]; static char *login_dbarray[] = { NULL, NULL, NULL }; me = (name != NULL && strcmp(name, LOGIN_MECLASS) == 0); dir = (!me || pwd == NULL) ? NULL : pwd->pw_dir; /* * Switch to user mode before checking/reading its ~/.login_conf * - some NFSes have root read access disabled. * * XXX: This fails to configure additional groups. */ if (dir) { euid = geteuid(); egid = getegid(); (void)setegid(pwd->pw_gid); (void)seteuid(pwd->pw_uid); } if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, _FILE_LOGIN_CONF) < MAXPATHLEN) { if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) login_dbarray[i++] = userpath; } /* * XXX: Why to add the system database if the class is `me'? */ if (_secure_path(path_login_conf, 0, 0) != -1) login_dbarray[i++] = path_login_conf; login_dbarray[i] = NULL; memset(lc, 0, sizeof(login_cap_t)); lc->lc_cap = lc->lc_class = lc->lc_style = NULL; if (name == NULL || *name == '\0') name = LOGIN_DEFCLASS; switch (cgetent(&lc->lc_cap, login_dbarray, name)) { case -1: /* Failed, entry does not exist */ if (me) break; /* Don't retry default on 'me' */ if (i == 0) r = -1; else if ((r = open(login_dbarray[0], O_RDONLY | O_CLOEXEC)) >= 0) close(r); /* * If there's at least one login class database, * and we aren't searching for a default class * then complain about a non-existent class. */ if (r >= 0 || strcmp(name, LOGIN_DEFCLASS) != 0) syslog(LOG_ERR, "login_getclass: unknown class '%s'", name); /* fall-back to default class */ name = LOGIN_DEFCLASS; msg = "%s: no default/fallback class '%s'"; if (cgetent(&lc->lc_cap, login_dbarray, name) != 0 && r >= 0) break; /* FALLTHROUGH - just return system defaults */ case 0: /* success! */ if ((lc->lc_class = strdup(name)) != NULL) { if (dir) { (void)seteuid(euid); (void)setegid(egid); } ++lc_object_count; return lc; } msg = "%s: strdup: %m"; break; case -2: msg = "%s: retrieving class information: %m"; break; case -3: msg = "%s: 'tc=' reference loop '%s'"; break; case 1: msg = "couldn't resolve 'tc=' reference in '%s'"; break; default: msg = "%s: unexpected cgetent() error '%s': %m"; break; } if (dir) { (void)seteuid(euid); (void)setegid(egid); } if (msg != NULL) syslog(LOG_ERR, msg, "login_getclass", name); free(lc); } return NULL; } /* * login_getclass() * Get the login class for the system (only) login class database. * Return a filled-out login_cap_t structure, including * class name, and the capability record buffer. */ login_cap_t * login_getclass(const char *cls) { return login_getclassbyname(cls, NULL); } /* * login_getpwclass() * Get the login class for a given password entry from * the system (only) login class database. * If the password entry's class field is not set, or * the class specified does not exist, then use the * default of LOGIN_DEFCLASS (i.e., "default") for an unprivileged * user or that of LOGIN_DEFROOTCLASS (i.e., "root") for a super-user. * Return a filled-out login_cap_t structure, including * class name, and the capability record buffer. */ login_cap_t * login_getpwclass(const struct passwd *pwd) { const char *cls = NULL; if (pwd != NULL) { cls = pwd->pw_class; if (cls == NULL || *cls == '\0') cls = (pwd->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS; } /* * XXX: pwd should be unused by login_getclassbyname() unless cls is `me', * so NULL can be passed instead of pwd for more safety. */ return login_getclassbyname(cls, pwd); } /* * login_getuserclass() * Get the `me' login class, allowing user overrides via ~/.login_conf. * Note that user overrides are allowed only in the `me' class. */ login_cap_t * login_getuserclass(const struct passwd *pwd) { return login_getclassbyname(LOGIN_MECLASS, pwd); } /* * login_getcapstr() * Given a login_cap entry, and a capability name, return the * value defined for that capability, a default if not found, or * an error string on error. */ const char * login_getcapstr(login_cap_t *lc, const char *cap, const char *def, const char *error) { char *res; int ret; if (lc == NULL || cap == NULL || lc->lc_cap == NULL || *cap == '\0') return def; if ((ret = cgetstr(lc->lc_cap, cap, &res)) == -1) return def; return (ret >= 0) ? res : error; } /* * login_getcaplist() * Given a login_cap entry, and a capability name, return the * value defined for that capability split into an array of * strings. */ const char ** login_getcaplist(login_cap_t *lc, const char *cap, const char *chars) { const char *lstring; if (chars == NULL) chars = ", \t"; if ((lstring = login_getcapstr(lc, cap, NULL, NULL)) != NULL) return arrayize(lstring, chars, NULL); return NULL; } /* * login_getpath() * From the login_cap_t , get the capability which is * formatted as either a space or comma delimited list of paths * and append them all into a string and separate by semicolons. * If there is an error of any kind, return . */ const char * login_getpath(login_cap_t *lc, const char *cap, const char *error) { const char *str; char *ptr; int count; str = login_getcapstr(lc, cap, NULL, NULL); if (str == NULL) return error; ptr = __DECONST(char *, str); /* XXXX Yes, very dodgy */ while (*ptr) { count = strcspn(ptr, ", \t"); ptr += count; if (*ptr) *ptr++ = ':'; } return str; } static int isinfinite(const char *s) { static const char *infs[] = { "infinity", "inf", "unlimited", "unlimit", "-1", NULL }; const char **i = &infs[0]; while (*i != NULL) { if (strcasecmp(s, *i) == 0) return 1; ++i; } return 0; } static u_quad_t rmultiply(u_quad_t n1, u_quad_t n2) { u_quad_t m, r; int b1, b2; static int bpw = 0; /* Handle simple cases */ if (n1 == 0 || n2 == 0) return 0; if (n1 == 1) return n2; if (n2 == 1) return n1; /* * sizeof() returns number of bytes needed for storage. * This may be different from the actual number of useful bits. */ if (!bpw) { bpw = sizeof(u_quad_t) * 8; while (((u_quad_t)1 << (bpw-1)) == 0) --bpw; } /* * First check the magnitude of each number. If the sum of the * magnatude is way to high, reject the number. (If this test * is not done then the first multiply below may overflow.) */ for (b1 = bpw; (((u_quad_t)1 << (b1-1)) & n1) == 0; --b1) ; for (b2 = bpw; (((u_quad_t)1 << (b2-1)) & n2) == 0; --b2) ; if (b1 + b2 - 2 > bpw) { errno = ERANGE; return (UQUAD_MAX); } /* * Decompose the multiplication to be: * h1 = n1 & ~1 * h2 = n2 & ~1 * l1 = n1 & 1 * l2 = n2 & 1 * (h1 + l1) * (h2 + l2) * (h1 * h2) + (h1 * l2) + (l1 * h2) + (l1 * l2) * * Since h1 && h2 do not have the low bit set, we can then say: * * (h1>>1 * h2>>1 * 4) + ... * * So if (h1>>1 * h2>>1) > (1<<(bpw - 2)) then the result will * overflow. * * Finally, if MAX - ((h1 * l2) + (l1 * h2) + (l1 * l2)) < (h1*h2) * then adding in residual amout will cause an overflow. */ m = (n1 >> 1) * (n2 >> 1); if (m >= ((u_quad_t)1 << (bpw-2))) { errno = ERANGE; return (UQUAD_MAX); } m *= 4; r = (n1 & n2 & 1) + (n2 & 1) * (n1 & ~(u_quad_t)1) + (n1 & 1) * (n2 & ~(u_quad_t)1); if ((u_quad_t)(m + r) < m) { errno = ERANGE; return (UQUAD_MAX); } m += r; return (m); } /* * login_getcaptime() * From the login_cap_t , get the capability , which is * formatted as a time (e.g., "=10h3m2s"). If is not * present in , return ; if there is an error of some kind, * return . */ rlim_t login_getcaptime(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) { char *res, *ep, *oval; int r; rlim_t tot; errno = 0; if (lc == NULL || lc->lc_cap == NULL) return def; /* * Look for in lc_cap. * If it's not there (-1), return . * If there's an error, return . */ if ((r = cgetstr(lc->lc_cap, cap, &res)) == -1) return def; else if (r < 0) { errno = ERANGE; return error; } /* "inf" and "infinity" are special cases */ if (isinfinite(res)) return RLIM_INFINITY; /* * Now go through the string, turning something like 1h2m3s into * an integral value. Whee. */ errno = 0; tot = 0; oval = res; while (*res) { rlim_t tim = strtoq(res, &ep, 0); rlim_t mult = 1; if (ep == NULL || ep == res || errno != 0) { invalid: syslog(LOG_WARNING, "login_getcaptime: class '%s' bad value %s=%s", lc->lc_class, cap, oval); errno = ERANGE; return error; } /* Look for suffixes */ switch (*ep++) { case 0: ep--; break; /* end of string */ case 's': case 'S': /* seconds */ break; case 'm': case 'M': /* minutes */ mult = 60; break; case 'h': case 'H': /* hours */ mult = 60L * 60L; break; case 'd': case 'D': /* days */ mult = 60L * 60L * 24L; break; case 'w': case 'W': /* weeks */ mult = 60L * 60L * 24L * 7L; break; case 'y': case 'Y': /* 365-day years */ mult = 60L * 60L * 24L * 365L; break; default: goto invalid; } res = ep; tot += rmultiply(tim, mult); if (errno) goto invalid; } return tot; } /* * login_getcapnum() * From the login_cap_t , extract the numerical value . * If it is not present, return for a default, and return * if there is an error. * Like login_getcaptime(), only it only converts to a number, not * to a time; "infinity" and "inf" are 'special.' */ rlim_t login_getcapnum(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) { char *ep, *res; int r; rlim_t val; if (lc == NULL || lc->lc_cap == NULL) return def; /* * For BSDI compatibility, try for the tag= first */ if ((r = cgetstr(lc->lc_cap, cap, &res)) == -1) { long lval; /* string capability not present, so try for tag# as numeric */ if ((r = cgetnum(lc->lc_cap, cap, &lval)) == -1) return def; /* Not there, so return default */ else if (r >= 0) return (rlim_t)lval; } if (r < 0) { errno = ERANGE; return error; } if (isinfinite(res)) return RLIM_INFINITY; errno = 0; val = strtoq(res, &ep, 0); if (ep == NULL || ep == res || errno != 0) { syslog(LOG_WARNING, "login_getcapnum: class '%s' bad value %s=%s", lc->lc_class, cap, res); errno = ERANGE; return error; } return val; } /* * login_getcapsize() * From the login_cap_t , extract the capability , which is * formatted as a size (e.g., "=10M"); it can also be "infinity". * If not present, return , or if there is an error of * some sort. */ rlim_t login_getcapsize(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) { char *ep, *res, *oval; int r; rlim_t tot; if (lc == NULL || lc->lc_cap == NULL) return def; if ((r = cgetstr(lc->lc_cap, cap, &res)) == -1) return def; else if (r < 0) { errno = ERANGE; return error; } if (isinfinite(res)) return RLIM_INFINITY; errno = 0; tot = 0; oval = res; while (*res) { rlim_t siz = strtoq(res, &ep, 0); rlim_t mult = 1; if (ep == NULL || ep == res || errno != 0) { invalid: syslog(LOG_WARNING, "login_getcapsize: class '%s' bad value %s=%s", lc->lc_class, cap, oval); errno = ERANGE; return error; } switch (*ep++) { case 0: /* end of string */ ep--; break; case 'b': case 'B': /* 512-byte blocks */ mult = 512; break; case 'k': case 'K': /* 1024-byte Kilobytes */ mult = 1024; break; case 'm': case 'M': /* 1024-k kbytes */ mult = 1024 * 1024; break; case 'g': case 'G': /* 1Gbyte */ mult = 1024 * 1024 * 1024; break; case 't': case 'T': /* 1TBte */ mult = 1024LL * 1024LL * 1024LL * 1024LL; break; default: goto invalid; } res = ep; tot += rmultiply(siz, mult); if (errno) goto invalid; } return tot; } /* * login_getcapbool() * From the login_cap_t , check for the existance of the capability * of . Return if ->lc_cap is NULL, otherwise return * the whether or not exists there. */ int login_getcapbool(login_cap_t *lc, const char *cap, int def) { if (lc == NULL || lc->lc_cap == NULL) return def; return (cgetcap(lc->lc_cap, cap, ':') != NULL); } /* * login_getstyle() * Given a login_cap entry , and optionally a type of auth , * and optionally a style