freebsd-libs-9.2+ds2/0000755000000000000000000000000012244372433011303 5ustar freebsd-libs-9.2+ds2/lib/0000755000000000000000000000000012244372541012051 5ustar freebsd-libs-9.2+ds2/lib/libusbhid/0000755000000000000000000000000012244372513014015 5ustar freebsd-libs-9.2+ds2/lib/libusbhid/usbhid.30000644000000000000000000001703512051100514015347 0ustar .\" $NetBSD: usb.3,v 1.13 2000/09/24 02:17:52 augustss Exp $ .\" .\" Copyright (c) 1999, 2001 Lennart Augustsson .\" 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 27, 2009 .Dt USBHID 3 .Os .Sh NAME .Nm usbhid , .Nm hid_get_report_desc , .Nm hid_get_report_id , .Nm hid_use_report_desc , .Nm hid_dispose_report_desc , .Nm hid_start_parse , .Nm hid_end_parse , .Nm hid_get_item , .Nm hid_report_size , .Nm hid_locate , .Nm hid_usage_page , .Nm hid_usage_in_page , .Nm hid_init , .Nm hid_get_data , .Nm hid_set_data , .Nm hid_get_report , .Nm hid_set_report .Nd USB HID access routines .Sh LIBRARY .Lb libusbhid .Sh SYNOPSIS .In usbhid.h .Ft report_desc_t .Fn hid_get_report_desc "int file" .Ft int .Fn hid_get_report_id "int file" .Ft int .Fn hid_set_immed "int fd" "int enable" .Ft report_desc_t .Fn hid_use_report_desc "unsigned char *data" "unsigned int size" .Ft void .Fn hid_dispose_report_desc "report_desc_t d" .Ft hid_data_t .Fn hid_start_parse "report_desc_t d" "int kindset" "int id" .Ft void .Fn hid_end_parse "hid_data_t s" .Ft int .Fn hid_get_item "hid_data_t s" "hid_item_t *h" .Ft int .Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int id" .Ft int .Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" "int id" .Ft "const char *" .Fn hid_usage_page "int i" .Ft "const char *" .Fn hid_usage_in_page "u_int u" .Ft int .Fn hid_parse_usage_page "const char *" .Ft int .Fn hid_parse_usage_in_page "const char *" .Ft void .Fn hid_init "const char *file" .Ft int .Fn hid_get_data "const void *data" "const hid_item_t *h" .Ft void .Fn hid_set_data "void *buf" "const hid_item_t *h" "int data" .Ft int .Fn hid_get_report "int fd" "enum hid_kind k" "unsigned char *data" "unsigned int size" .Ft int .Fn hid_set_report "int fd" "enum hid_kind k" "unsigned char *data" "unsigned int size" .Sh DESCRIPTION The .Nm library provides routines to extract data from USB Human Interface Devices. .Ss Introduction USB HID devices send and receive data layed out in a device dependent way. The .Nm library contains routines to extract the .Em "report descriptor" which contains the data layout information and then use this information. .Pp The routines can be divided into four parts: extraction of the descriptor, parsing of the descriptor, translating to/from symbolic names, and data manipulation. .Ss Synchronous HID operation Synchronous HID operation can be enabled or disabled by a call to .Fn hid_set_immed . If the second argument is zero synchronous HID operation is disabled. Else synchronous HID operation is enabled. The function returns a negative value on failure. .Pp .Fn hid_get_report and .Fn hid_set_report functions allow to synchronously get and set specific report if device supports it. For devices with multiple report IDs, wanted ID should be provided in the first byte of the buffer for both get and set. .Ss Descriptor Functions The report descriptor ID can be obtained by calling .Fn hid_get_report_id . A report descriptor can be obtained by calling .Fn hid_get_report_desc with a file descriptor obtained by opening a .Xr uhid 4 device. Alternatively a data buffer containing the report descriptor can be passed into .Fn hid_use_report_desc . The data is copied into an internal structure. When the report descriptor is no longer needed it should be freed by calling .Fn hid_dispose_report_desc . The type .Vt report_desc_t is opaque and should be used when calling the parsing functions. If .Fn hid_dispose_report_desc fails it will return .Dv NULL . .Ss Descriptor Parsing Functions To parse the report descriptor the .Fn hid_start_parse function should be called with a report descriptor, a set that describes which items that are interesting, and the desired report ID (or -1 to obtain items of all report IDs). The set is obtained by OR-ing together values .Fa "(1 << k)" where .Fa k is an item of type .Vt hid_kind_t . The function returns .Dv NULL if the initialization fails, otherwise an opaque value to be used in subsequent calls. After parsing the .Fn hid_end_parse function should be called to free internal data structures. .Pp To iterate through all the items in the report descriptor .Fn hid_get_item should be called while it returns a value greater than 0. When the report descriptor ends it will returns 0; a syntax error within the report descriptor will cause a return value less than 0. The struct pointed to by .Fa h will be filled with the relevant data for the item. The definition of .Vt hid_item_t can be found in .In usbhid.h and the meaning of the components in the USB HID documentation. .Pp Data should be read/written to the device in the size of the report. The size of a report (of a certain kind) can be computed by the .Fn hid_report_size function. If the report is prefixed by an ID byte it is given by .Fa id . .Pp To locate a single item the .Fn hid_locate function can be used. It should be given the usage code of the item and its kind and it will fill the item and return non-zero if the item was found. .Ss Name Translation Functions The function .Fn hid_usage_page will return the symbolic name of a usage page, and the function .Fn hid_usage_in_page will return the symbolic name of the usage within the page. Both these functions may return a pointer to static data. .Pp The functions .Fn hid_parse_usage_page and .Fn hid_parse_usage_in_page are the inverses of .Fn hid_usage_page and .Fn hid_usage_in_page . They take a usage string and return the number of the usage, or \-1 if it cannot be found. .Pp Before any of these functions can be called the usage table must be parsed, this is done by calling .Fn hid_init with the name of the table. Passing .Dv NULL to this function will cause it to use the default table. .Ss Data Extraction Functions Given the data obtained from a HID device and an item in the report descriptor the .Fn hid_get_data function extracts the value of the item. Conversely .Fn hid_set_data can be used to put data into a report (which must be zeroed first). .Sh FILES .Bl -tag -width ".Pa /usr/share/misc/usb_hid_usages" .It Pa /usr/share/misc/usb_hid_usages The default HID usage table. .El .Sh EXAMPLES Not yet. .Sh SEE ALSO The .Tn USB specifications can be found at .Pa http://www.usb.org/developers/docs/ . .Pp .Xr uhid 4 , .Xr usb 4 .Sh HISTORY The .Nm library first appeared in .Nx 1.5 . .Sh BUGS This man page is woefully incomplete. freebsd-libs-9.2+ds2/lib/libusbhid/parse.c0000644000000000000000000003103712051100514015261 0ustar /* $NetBSD: parse.c,v 1.11 2000/09/24 02:19:54 augustss Exp $ */ /* * Copyright (c) 1999, 2001 Lennart Augustsson * 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 "usbhid.h" #include "usbvar.h" #define MAXUSAGE 100 #define MAXPUSH 4 #define MAXID 64 #define ITEMTYPES 3 struct hid_pos_data { int32_t rid; uint32_t pos[ITEMTYPES]; }; struct hid_data { const uint8_t *start; const uint8_t *end; const uint8_t *p; struct hid_item cur[MAXPUSH]; struct hid_pos_data last_pos[MAXID]; uint32_t pos[ITEMTYPES]; int32_t usages_min[MAXUSAGE]; int32_t usages_max[MAXUSAGE]; int32_t usage_last; /* last seen usage */ uint32_t loc_size; /* last seen size */ uint32_t loc_count; /* last seen count */ uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ uint8_t pushlevel; /* current pushlevel */ uint8_t ncount; /* end usage item count */ uint8_t icount; /* current usage item count */ uint8_t nusage; /* end "usages_min/max" index */ uint8_t iusage; /* current "usages_min/max" index */ uint8_t ousage; /* current "usages_min/max" offset */ uint8_t susage; /* usage set flags */ int32_t reportid; /* requested report ID */ }; /*------------------------------------------------------------------------* * hid_clear_local *------------------------------------------------------------------------*/ static void hid_clear_local(hid_item_t *c) { c->usage = 0; c->usage_minimum = 0; c->usage_maximum = 0; c->designator_index = 0; c->designator_minimum = 0; c->designator_maximum = 0; c->string_index = 0; c->string_minimum = 0; c->string_maximum = 0; c->set_delimiter = 0; } static void hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) { uint8_t i, j; /* check for same report ID - optimise */ if (c->report_ID == next_rID) return; /* save current position for current rID */ if (c->report_ID == 0) { i = 0; } else { for (i = 1; i != MAXID; i++) { if (s->last_pos[i].rid == c->report_ID) break; if (s->last_pos[i].rid == 0) break; } } if (i != MAXID) { s->last_pos[i].rid = c->report_ID; for (j = 0; j < ITEMTYPES; j++) s->last_pos[i].pos[j] = s->pos[j]; } /* store next report ID */ c->report_ID = next_rID; /* lookup last position for next rID */ if (next_rID == 0) { i = 0; } else { for (i = 1; i != MAXID; i++) { if (s->last_pos[i].rid == next_rID) break; if (s->last_pos[i].rid == 0) break; } } if (i != MAXID) { s->last_pos[i].rid = next_rID; for (j = 0; j < ITEMTYPES; j++) s->pos[j] = s->last_pos[i].pos[j]; } else { for (j = 0; j < ITEMTYPES; j++) s->pos[j] = 0; /* Out of RID entries. */ } } /*------------------------------------------------------------------------* * hid_start_parse *------------------------------------------------------------------------*/ hid_data_t hid_start_parse(report_desc_t d, int kindset, int id) { struct hid_data *s; s = malloc(sizeof *s); memset(s, 0, sizeof *s); s->start = s->p = d->data; s->end = d->data + d->size; s->kindset = kindset; s->reportid = id; return (s); } /*------------------------------------------------------------------------* * hid_end_parse *------------------------------------------------------------------------*/ void hid_end_parse(hid_data_t s) { if (s == NULL) return; free(s); } /*------------------------------------------------------------------------* * get byte from HID descriptor *------------------------------------------------------------------------*/ static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize) { const uint8_t *ptr; uint8_t retval; ptr = s->p; /* check if end is reached */ if (ptr == s->end) return (0); /* read out a byte */ retval = *ptr; /* check if data pointer can be advanced by "wSize" bytes */ if ((s->end - ptr) < wSize) ptr = s->end; else ptr += wSize; /* update pointer */ s->p = ptr; return (retval); } /*------------------------------------------------------------------------* * hid_get_item *------------------------------------------------------------------------*/ static int hid_get_item_raw(hid_data_t s, hid_item_t *h) { hid_item_t *c; unsigned int bTag, bType, bSize; int32_t mask; int32_t dval; if (s == NULL) return (0); c = &s->cur[s->pushlevel]; top: /* check if there is an array of items */ if (s->icount < s->ncount) { /* get current usage */ if (s->iusage < s->nusage) { dval = s->usages_min[s->iusage] + s->ousage; c->usage = dval; s->usage_last = dval; if (dval == s->usages_max[s->iusage]) { s->iusage ++; s->ousage = 0; } else { s->ousage ++; } } else { /* Using last usage */ dval = s->usage_last; } s->icount ++; /* * Only copy HID item, increment position and return * if correct kindset! */ if (s->kindset & (1 << c->kind)) { *h = *c; h->pos = s->pos[c->kind]; s->pos[c->kind] += c->report_size * c->report_count; return (1); } } /* reset state variables */ s->icount = 0; s->ncount = 0; s->iusage = 0; s->nusage = 0; s->susage = 0; s->ousage = 0; hid_clear_local(c); /* get next item */ while (s->p != s->end) { bSize = hid_get_byte(s, 1); if (bSize == 0xfe) { /* long item */ bSize = hid_get_byte(s, 1); bSize |= hid_get_byte(s, 1) << 8; bTag = hid_get_byte(s, 1); bType = 0xff; /* XXX what should it be */ } else { /* short item */ bTag = bSize >> 4; bType = (bSize >> 2) & 3; bSize &= 3; if (bSize == 3) bSize = 4; } switch(bSize) { case 0: dval = 0; mask = 0; break; case 1: dval = (int8_t)hid_get_byte(s, 1); mask = 0xFF; break; case 2: dval = hid_get_byte(s, 1); dval |= hid_get_byte(s, 1) << 8; dval = (int16_t)dval; mask = 0xFFFF; break; case 4: dval = hid_get_byte(s, 1); dval |= hid_get_byte(s, 1) << 8; dval |= hid_get_byte(s, 1) << 16; dval |= hid_get_byte(s, 1) << 24; mask = 0xFFFFFFFF; break; default: dval = hid_get_byte(s, bSize); continue; } switch (bType) { case 0: /* Main */ switch (bTag) { case 8: /* Input */ c->kind = hid_input; c->flags = dval; ret: c->report_count = s->loc_count; c->report_size = s->loc_size; if (c->flags & HIO_VARIABLE) { /* range check usage count */ if (c->report_count > 255) { s->ncount = 255; } else s->ncount = c->report_count; /* * The "top" loop will return * one and one item: */ c->report_count = 1; c->usage_minimum = 0; c->usage_maximum = 0; } else { s->ncount = 1; } goto top; case 9: /* Output */ c->kind = hid_output; c->flags = dval; goto ret; case 10: /* Collection */ c->kind = hid_collection; c->collection = dval; c->collevel++; c->usage = s->usage_last; *h = *c; return (1); case 11: /* Feature */ c->kind = hid_feature; c->flags = dval; goto ret; case 12: /* End collection */ c->kind = hid_endcollection; if (c->collevel == 0) { /* Invalid end collection. */ return (0); } c->collevel--; *h = *c; return (1); default: break; } break; case 1: /* Global */ switch (bTag) { case 0: c->_usage_page = dval << 16; break; case 1: c->logical_minimum = dval; break; case 2: c->logical_maximum = dval; break; case 3: c->physical_minimum = dval; break; case 4: c->physical_maximum = dval; break; case 5: c->unit_exponent = dval; break; case 6: c->unit = dval; break; case 7: /* mask because value is unsigned */ s->loc_size = dval & mask; break; case 8: hid_switch_rid(s, c, dval & mask); break; case 9: /* mask because value is unsigned */ s->loc_count = dval & mask; break; case 10: /* Push */ s->pushlevel ++; if (s->pushlevel < MAXPUSH) { s->cur[s->pushlevel] = *c; /* store size and count */ c->report_size = s->loc_size; c->report_count = s->loc_count; /* update current item pointer */ c = &s->cur[s->pushlevel]; } break; case 11: /* Pop */ s->pushlevel --; if (s->pushlevel < MAXPUSH) { c = &s->cur[s->pushlevel]; /* restore size and count */ s->loc_size = c->report_size; s->loc_count = c->report_count; c->report_size = 0; c->report_count = 0; } break; default: break; } break; case 2: /* Local */ switch (bTag) { case 0: if (bSize != 4) dval = (dval & mask) | c->_usage_page; /* set last usage, in case of a collection */ s->usage_last = dval; if (s->nusage < MAXUSAGE) { s->usages_min[s->nusage] = dval; s->usages_max[s->nusage] = dval; s->nusage ++; } /* else XXX */ /* clear any pending usage sets */ s->susage = 0; break; case 1: s->susage |= 1; if (bSize != 4) dval = (dval & mask) | c->_usage_page; c->usage_minimum = dval; goto check_set; case 2: s->susage |= 2; if (bSize != 4) dval = (dval & mask) | c->_usage_page; c->usage_maximum = dval; check_set: if (s->susage != 3) break; /* sanity check */ if ((s->nusage < MAXUSAGE) && (c->usage_minimum <= c->usage_maximum)) { /* add usage range */ s->usages_min[s->nusage] = c->usage_minimum; s->usages_max[s->nusage] = c->usage_maximum; s->nusage ++; } /* else XXX */ s->susage = 0; break; case 3: c->designator_index = dval; break; case 4: c->designator_minimum = dval; break; case 5: c->designator_maximum = dval; break; case 7: c->string_index = dval; break; case 8: c->string_minimum = dval; break; case 9: c->string_maximum = dval; break; case 10: c->set_delimiter = dval; break; default: break; } break; default: break; } } return (0); } int hid_get_item(hid_data_t s, hid_item_t *h) { int r; for (;;) { r = hid_get_item_raw(s, h); if (r <= 0 || s->reportid == -1 || h->report_ID == s->reportid) break; } return (r); } int hid_report_size(report_desc_t r, enum hid_kind k, int id) { struct hid_data *d; struct hid_item h; uint32_t temp; uint32_t hpos; uint32_t lpos; int report_id = 0; hpos = 0; lpos = 0xFFFFFFFF; memset(&h, 0, sizeof h); for (d = hid_start_parse(r, 1 << k, id); hid_get_item(d, &h); ) { if (h.kind == k) { /* compute minimum */ if (lpos > h.pos) lpos = h.pos; /* compute end position */ temp = h.pos + (h.report_size * h.report_count); /* compute maximum */ if (hpos < temp) hpos = temp; if (h.report_ID != 0) report_id = 1; } } hid_end_parse(d); /* safety check - can happen in case of currupt descriptors */ if (lpos > hpos) temp = 0; else temp = hpos - lpos; /* return length in bytes rounded up */ return ((temp + 7) / 8 + report_id); } int hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k, hid_item_t *h, int id) { struct hid_data *d; for (d = hid_start_parse(desc, 1 << k, id); hid_get_item(d, h); ) { if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) { hid_end_parse(d); return (1); } } hid_end_parse(d); h->report_size = 0; return (0); } freebsd-libs-9.2+ds2/lib/libusbhid/Makefile0000644000000000000000000000116211456305225015455 0ustar # $NetBSD: Makefile,v 1.5 1999/07/23 09:44:38 mrg Exp $ # $FreeBSD$ LIB= usbhid MAN= usbhid.3 SHLIB_MAJOR= 4 MLINKS= usbhid.3 libusbhid.3 usbhid.3 hid_get_report_desc.3 \ usbhid.3 hid_dispose_report_desc.3 \ usbhid.3 hid_start_parse.3 usbhid.3 hid_end_parse.3 \ usbhid.3 hid_get_item.3 usbhid.3 hid_report_size.3 \ usbhid.3 hid_locate.3 \ usbhid.3 hid_usage_page.3 usbhid.3 hid_usage_in_page.3 \ usbhid.3 hid_init.3 \ usbhid.3 hid_get_data.3 usbhid.3 hid_set_data.3 SRCS= descr.c descr_compat.c parse.c usage.c data.c INCS= usbhid.h .if defined(COMPAT_32BIT) CFLAGS+= -DCOMPAT_32BIT .endif .include freebsd-libs-9.2+ds2/lib/libusbhid/descr_compat.c0000644000000000000000000000435311150566306016631 0ustar /* * Copyright (c) 1999 Lennart Augustsson * 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. */ /* * This file contains fallback-compatibility code for the old FreeBSD * USB stack. */ #ifdef HID_COMPAT7 #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include "usbhid.h" #include "usbvar.h" int hid_set_immed_compat7(int fd, int enable) { return (ioctl(fd, USB_SET_IMMED, &enable)); } int hid_get_report_id_compat7(int fd) { int temp = -1; if (ioctl(fd, USB_GET_REPORT_ID, &temp) < 0) return (-1); return (temp); } report_desc_t hid_get_report_desc_compat7(int fd) { struct usb_ctl_report_desc rep; rep.ucrd_size = 0; if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0) return (NULL); return (hid_use_report_desc(rep.ucrd_data, (unsigned int)rep.ucrd_size)); } #endif /* HID_COMPAT7 */ freebsd-libs-9.2+ds2/lib/libusbhid/descr.c0000644000000000000000000000776312051100514015260 0ustar /* $NetBSD: descr.c,v 1.9 2000/09/24 02:13:24 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson * 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 "usbhid.h" #include "usbvar.h" int hid_set_immed(int fd, int enable) { int ret; ret = ioctl(fd, USB_SET_IMMED, &enable); #ifdef HID_COMPAT7 if (ret < 0) ret = hid_set_immed_compat7(fd, enable); #endif return (ret); } int hid_get_report_id(int fd) { report_desc_t rep; hid_data_t d; hid_item_t h; int kindset; int temp = -1; int ret; if ((rep = hid_get_report_desc(fd)) == NULL) goto use_ioctl; kindset = 1 << hid_input | 1 << hid_output | 1 << hid_feature; for (d = hid_start_parse(rep, kindset, -1); hid_get_item(d, &h); ) { /* Return the first report ID we met. */ if (h.report_ID != 0) { temp = h.report_ID; break; } } hid_end_parse(d); hid_dispose_report_desc(rep); if (temp > 0) return (temp); use_ioctl: ret = ioctl(fd, USB_GET_REPORT_ID, &temp); #ifdef HID_COMPAT7 if (ret < 0) ret = hid_get_report_id_compat7(fd); else #endif ret = temp; return (ret); } report_desc_t hid_get_report_desc(int fd) { struct usb_gen_descriptor ugd; report_desc_t rep; void *data; memset(&ugd, 0, sizeof(ugd)); /* get actual length first */ ugd.ugd_data = hid_pass_ptr(NULL); ugd.ugd_maxlen = 65535; if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) { #ifdef HID_COMPAT7 /* could not read descriptor */ /* try FreeBSD 7 compat code */ return (hid_get_report_desc_compat7(fd)); #else return (NULL); #endif } /* * NOTE: The kernel will return a failure if * "ugd_actlen" is zero. */ data = malloc(ugd.ugd_actlen); if (data == NULL) return (NULL); /* fetch actual descriptor */ ugd.ugd_data = hid_pass_ptr(data); ugd.ugd_maxlen = ugd.ugd_actlen; if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) { /* could not read descriptor */ free(data); return (NULL); } /* sanity check */ if (ugd.ugd_actlen < 1) { /* invalid report descriptor */ free(data); return (NULL); } /* check END_COLLECTION */ if (((unsigned char *)data)[ugd.ugd_actlen -1] != 0xC0) { /* invalid end byte */ free(data); return (NULL); } rep = hid_use_report_desc(data, ugd.ugd_actlen); free(data); return (rep); } report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size) { report_desc_t r; r = malloc(sizeof(*r) + size); if (r == 0) { errno = ENOMEM; return (NULL); } r->size = size; memcpy(r->data, data, size); return (r); } void hid_dispose_report_desc(report_desc_t r) { free(r); } freebsd-libs-9.2+ds2/lib/libusbhid/usage.c0000644000000000000000000001310011353335420015254 0ustar /* $NetBSD: usage.c,v 1.8 2000/10/10 19:23:58 is Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson * 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 "usbhid.h" #define _PATH_HIDTABLE "/usr/share/misc/usb_hid_usages" struct usage_in_page { const char *name; int usage; }; static struct usage_page { const char *name; int usage; struct usage_in_page *page_contents; int pagesize, pagesizemax; } *pages; static int npages, npagesmax; #ifdef DEBUG void dump_hid_table(void) { int i, j; for (i = 0; i < npages; i++) { printf("%d\t%s\n", pages[i].usage, pages[i].name); for (j = 0; j < pages[i].pagesize; j++) { printf("\t%d\t%s\n", pages[i].page_contents[j].usage, pages[i].page_contents[j].name); } } } #endif void hid_init(const char *hidname) { FILE *f; char line[100], name[100], *p, *n; int no; int lineno; struct usage_page *curpage = 0; if (hidname == 0) hidname = _PATH_HIDTABLE; f = fopen(hidname, "r"); if (f == NULL) err(1, "%s", hidname); for (lineno = 1; ; lineno++) { if (fgets(line, sizeof line, f) == NULL) break; if (line[0] == '#') continue; for (p = line; *p && isspace(*p); p++) ; if (!*p) continue; if (sscanf(line, " * %[^\n]", name) == 1) no = -1; else if (sscanf(line, " 0x%x %[^\n]", &no, name) != 2 && sscanf(line, " %d %[^\n]", &no, name) != 2) errx(1, "file %s, line %d, syntax error", hidname, lineno); for (p = name; *p; p++) if (isspace(*p) || *p == '.') *p = '_'; n = strdup(name); if (!n) err(1, "strdup"); if (isspace(line[0])) { if (!curpage) errx(1, "file %s, line %d, syntax error", hidname, lineno); if (curpage->pagesize >= curpage->pagesizemax) { curpage->pagesizemax += 10; curpage->page_contents = realloc(curpage->page_contents, curpage->pagesizemax * sizeof (struct usage_in_page)); if (!curpage->page_contents) err(1, "realloc"); } curpage->page_contents[curpage->pagesize].name = n; curpage->page_contents[curpage->pagesize].usage = no; curpage->pagesize++; } else { if (npages >= npagesmax) { if (pages == 0) { npagesmax = 5; pages = malloc(npagesmax * sizeof (struct usage_page)); } else { npagesmax += 5; pages = realloc(pages, npagesmax * sizeof (struct usage_page)); } if (!pages) err(1, "alloc"); } curpage = &pages[npages++]; curpage->name = n; curpage->usage = no; curpage->pagesize = 0; curpage->pagesizemax = 10; curpage->page_contents = malloc(curpage->pagesizemax * sizeof (struct usage_in_page)); if (!curpage->page_contents) err(1, "malloc"); } } fclose(f); #ifdef DEBUG dump_hid_table(); #endif } const char * hid_usage_page(int i) { static char b[10]; int k; if (!pages) errx(1, "no hid table"); for (k = 0; k < npages; k++) if (pages[k].usage == i) return pages[k].name; sprintf(b, "0x%04x", i); return b; } const char * hid_usage_in_page(unsigned int u) { int page = HID_PAGE(u); int i = HID_USAGE(u); static char b[100]; int j, k, us; for (k = 0; k < npages; k++) if (pages[k].usage == page) break; if (k >= npages) goto bad; for (j = 0; j < pages[k].pagesize; j++) { us = pages[k].page_contents[j].usage; if (us == -1) { sprintf(b, fmtcheck(pages[k].page_contents[j].name, "%d"), i); return b; } if (us == i) return pages[k].page_contents[j].name; } bad: sprintf(b, "0x%04x", i); return b; } int hid_parse_usage_page(const char *name) { int k; if (!pages) errx(1, "no hid table"); for (k = 0; k < npages; k++) if (strcmp(pages[k].name, name) == 0) return pages[k].usage; return -1; } /* XXX handle hex */ int hid_parse_usage_in_page(const char *name) { const char *sep; int k, j; unsigned int l; sep = strchr(name, ':'); if (sep == NULL) return -1; l = sep - name; for (k = 0; k < npages; k++) if (strncmp(pages[k].name, name, l) == 0) goto found; return -1; found: sep++; for (j = 0; j < pages[k].pagesize; j++) if (strcmp(pages[k].page_contents[j].name, sep) == 0) return (pages[k].usage << 16) | pages[k].page_contents[j].usage; return (-1); } freebsd-libs-9.2+ds2/lib/libusbhid/usbvar.h0000644000000000000000000000360511456305225015474 0ustar /* $NetBSD: usbvar.h,v 1.2 1999/05/11 21:15:46 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson * 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 _USBVAR_H_ #define _USBVAR_H_ struct report_desc { uint32_t size; uint8_t data[1]; }; /* internal backwards compatibility functions */ #ifdef HID_COMPAT7 int hid_set_immed_compat7(int fd, int enable); int hid_get_report_id_compat7(int fd); report_desc_t hid_get_report_desc_compat7(int fd); #endif #ifdef COMPAT_32BIT #define hid_pass_ptr(ptr) ((uint64_t)(uintptr_t)(ptr)) #else #define hid_pass_ptr(ptr) (ptr) #endif #endif /* _USBVAR_H_ */ freebsd-libs-9.2+ds2/lib/libusbhid/data.c0000644000000000000000000000721211700574373015100 0ustar /* $NetBSD: data.c,v 1.8 2000/04/02 11:10:53 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson * 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 "usbhid.h" #include "usbvar.h" int32_t hid_get_data(const void *p, const hid_item_t *h) { const uint8_t *buf; uint32_t hpos; uint32_t hsize; uint32_t data; int i, end, offs; buf = p; /* Skip report ID byte. */ if (h->report_ID > 0) buf++; hpos = h->pos; /* bit position of data */ hsize = h->report_size; /* bit length of data */ /* Range check and limit */ if (hsize == 0) return (0); if (hsize > 32) hsize = 32; offs = hpos / 8; end = (hpos + hsize) / 8 - offs; data = 0; for (i = 0; i <= end; i++) data |= buf[offs + i] << (i*8); /* Correctly shift down data */ data >>= hpos % 8; hsize = 32 - hsize; /* Mask and sign extend in one */ if ((h->logical_minimum < 0) || (h->logical_maximum < 0)) data = (int32_t)((int32_t)data << hsize) >> hsize; else data = (uint32_t)((uint32_t)data << hsize) >> hsize; return (data); } void hid_set_data(void *p, const hid_item_t *h, int32_t data) { uint8_t *buf; uint32_t hpos; uint32_t hsize; uint32_t mask; int i; int end; int offs; buf = p; /* Set report ID byte. */ if (h->report_ID > 0) *buf++ = h->report_ID & 0xff; hpos = h->pos; /* bit position of data */ hsize = h->report_size; /* bit length of data */ if (hsize != 32) { mask = (1 << hsize) - 1; data &= mask; } else mask = ~0; data <<= (hpos % 8); mask <<= (hpos % 8); mask = ~mask; offs = hpos / 8; end = (hpos + hsize) / 8 - offs; for (i = 0; i <= end; i++) buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) | ((data >> (i*8)) & 0xff); } int hid_get_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size) { struct usb_gen_descriptor ugd; memset(&ugd, 0, sizeof(ugd)); ugd.ugd_data = hid_pass_ptr(data); ugd.ugd_maxlen = size; ugd.ugd_report_type = k + 1; return (ioctl(fd, USB_GET_REPORT, &ugd)); } int hid_set_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size) { struct usb_gen_descriptor ugd; memset(&ugd, 0, sizeof(ugd)); ugd.ugd_data = hid_pass_ptr(data); ugd.ugd_maxlen = size; ugd.ugd_report_type = k + 1; return (ioctl(fd, USB_SET_REPORT, &ugd)); } freebsd-libs-9.2+ds2/lib/libusbhid/usbhid.h0000644000000000000000000000731011700574373015451 0ustar /* $NetBSD: usb.h,v 1.8 2000/08/13 22:22:02 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson * 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 typedef struct report_desc *report_desc_t; typedef struct hid_data *hid_data_t; typedef enum hid_kind { hid_input, hid_output, hid_feature, hid_collection, hid_endcollection } hid_kind_t; typedef struct hid_item { /* Global */ uint32_t _usage_page; int32_t logical_minimum; int32_t logical_maximum; int32_t physical_minimum; int32_t physical_maximum; int32_t unit_exponent; int32_t unit; int32_t report_size; int32_t report_ID; #define NO_REPORT_ID 0 int32_t report_count; /* Local */ uint32_t usage; int32_t usage_minimum; int32_t usage_maximum; int32_t designator_index; int32_t designator_minimum; int32_t designator_maximum; int32_t string_index; int32_t string_minimum; int32_t string_maximum; int32_t set_delimiter; /* Misc */ int32_t collection; int collevel; enum hid_kind kind; uint32_t flags; /* Location */ uint32_t pos; /* unused */ struct hid_item *next; } hid_item_t; #define HID_PAGE(u) (((u) >> 16) & 0xffff) #define HID_USAGE(u) ((u) & 0xffff) #define HID_HAS_GET_SET_REPORT 1 __BEGIN_DECLS /* Obtaining a report descriptor, descr.c: */ report_desc_t hid_get_report_desc(int file); report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size); void hid_dispose_report_desc(report_desc_t); int hid_get_report_id(int file); int hid_set_immed(int fd, int enable); /* Parsing of a HID report descriptor, parse.c: */ hid_data_t hid_start_parse(report_desc_t d, int kindset, int id); void hid_end_parse(hid_data_t s); int hid_get_item(hid_data_t s, hid_item_t *h); int hid_report_size(report_desc_t d, enum hid_kind k, int id); int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h, int id); /* Conversion to/from usage names, usage.c: */ const char *hid_usage_page(int i); const char *hid_usage_in_page(unsigned int u); void hid_init(const char *file); int hid_parse_usage_in_page(const char *name); int hid_parse_usage_page(const char *name); /* Extracting/insertion of data, data.c: */ int32_t hid_get_data(const void *p, const hid_item_t *h); void hid_set_data(void *p, const hid_item_t *h, int32_t data); int hid_get_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size); int hid_set_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size); __END_DECLS freebsd-libs-9.2+ds2/lib/libelf/0000755000000000000000000000000012244372453013310 5ustar freebsd-libs-9.2+ds2/lib/libelf/libelf_align.c0000644000000000000000000001052011421542132016046 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-9.2+ds2/lib/libelf/gelf_cap.c0000644000000000000000000000700210541424661015210 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-9.2+ds2/lib/libelf/_libelf.h0000644000000000000000000001504111421567012015047 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-9.2+ds2/lib/libelf/README0000644000000000000000000000064211130313462014156 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-9.2+ds2/lib/libelf/elf_getbase.c0000644000000000000000000000323211405134752015710 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-9.2+ds2/lib/libelf/libelf_shdr.c0000644000000000000000000000341110525402563015724 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-9.2+ds2/lib/libelf/gelf_fsize.c0000644000000000000000000000366110525402563015573 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-9.2+ds2/lib/libelf/gelf_fsize.30000644000000000000000000000544211421547141015510 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-9.2+ds2/lib/libelf/gelf_getehdr.30000644000000000000000000000666111361411226016013 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-9.2+ds2/lib/libelf/gelf_newehdr.30000644000000000000000000001150311755314130016017 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-9.2+ds2/lib/libelf/gelf_getsym.30000644000000000000000000000677011361411226015702 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-9.2+ds2/lib/libelf/elf_getbase.30000644000000000000000000000437411405134752015640 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-9.2+ds2/lib/libelf/elf_getscn.30000644000000000000000000001007211361411226015474 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-9.2+ds2/lib/libelf/elf_version.30000644000000000000000000000555611361411226015711 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-9.2+ds2/lib/libelf/elf_errmsg.30000644000000000000000000000672411361411226015521 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-9.2+ds2/lib/libelf/gelf_getmove.30000644000000000000000000000666111361411226016037 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-9.2+ds2/lib/libelf/elf_getshnum.30000644000000000000000000000503111421562272016047 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. .Pp .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-9.2+ds2/lib/libelf/elf_shnum.c0000644000000000000000000000372111421562272015433 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-9.2+ds2/lib/libelf/libelf_xlate.c0000644000000000000000000001014711421545376016113 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-9.2+ds2/lib/libelf/gelf_symshndx.c0000644000000000000000000000642510525402563016331 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-9.2+ds2/lib/libelf/gelf_rela.c0000644000000000000000000000747510762445046015413 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-9.2+ds2/lib/libelf/elf_errno.c0000644000000000000000000000335010525402563015424 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-9.2+ds2/lib/libelf/elf_strptr.30000644000000000000000000000640611755314130015560 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-9.2+ds2/lib/libelf/elf_rand.30000644000000000000000000000606411361411226015143 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-9.2+ds2/lib/libelf/libelf_allocate.c0000644000000000000000000001016710566777536016602 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-9.2+ds2/lib/libelf/gelf_newphdr.30000644000000000000000000000703411361411226016033 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-9.2+ds2/lib/libelf/libelf_data.c0000644000000000000000000000532111561115333015674 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_MIPS_DWARF: /* FALLTHROUGH */ case SHT_AMD64_UNWIND: /* == SHT_IA_64_UNWIND */ return (ELF_T_BYTE); default: return (-1); } } freebsd-libs-9.2+ds2/lib/libelf/elf_strptr.c0000644000000000000000000000707111015471710015634 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-9.2+ds2/lib/libelf/gelf_getphdr.30000644000000000000000000000757111755314130016032 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-9.2+ds2/lib/libelf/Version.map0000644000000000000000000000302611421562272015431 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-9.2+ds2/lib/libelf/elf_rand.c0000644000000000000000000000364410525402563015231 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-9.2+ds2/lib/libelf/elf_errmsg.c0000644000000000000000000000636110536561743015613 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. */ 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-9.2+ds2/lib/libelf/libelf_ar.c0000644000000000000000000001610711421567012015371 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-9.2+ds2/lib/libelf/elf_version.c0000644000000000000000000000330710525402563015766 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-9.2+ds2/lib/libelf/Makefile0000644000000000000000000000755611561115333014756 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 GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES= ${GENSRCS} CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../sys 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-9.2+ds2/lib/libelf/libelf.c0000644000000000000000000000360410525402563014710 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-9.2+ds2/lib/libelf/elf_phnum.c0000644000000000000000000000372111421562272015430 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-9.2+ds2/lib/libelf/elf_getphnum.30000644000000000000000000000535411421562272016054 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. .Pp .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-9.2+ds2/lib/libelf/gelf.30000644000000000000000000001423211361411226014302 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 .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 .It "Allocating ELF Data Structures" .Bl -tag -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 -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 -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 -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 -compact -width ".Fn gelf_update_shdr" .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-9.2+ds2/lib/libelf/elf_begin.30000644000000000000000000001503711453610460015306 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 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-9.2+ds2/lib/libelf/elf_types.m40000644000000000000000000001543511421551222015541 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-9.2+ds2/lib/libelf/elf_getarhdr.30000644000000000000000000000571311361411226016017 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-9.2+ds2/lib/libelf/gelf_getsyminfo.30000644000000000000000000000643211361411226016551 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-9.2+ds2/lib/libelf/elf_getarhdr.c0000644000000000000000000000316610525402563016104 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-9.2+ds2/lib/libelf/gelf_xlatetof.30000644000000000000000000001527611361411226016221 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-9.2+ds2/lib/libelf/elf_getphdrnum.30000644000000000000000000000521311421562272016374 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 .Os .Dt ELF_GETPHDRNUM 3 .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. .Pp .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-9.2+ds2/lib/libelf/gelf_ehdr.c0000644000000000000000000001007011421533314015360 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-9.2+ds2/lib/libelf/elf.30000644000000000000000000004142011767532253014150 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 indent .It "Archive Access" .Bl -tag -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 -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 -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 -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 -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 ".Fn elf_setshstrndx" -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 ".Fn elf_getshstrndx" -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-9.2+ds2/lib/libelf/elf_begin.c0000644000000000000000000000762311421571701015367 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-9.2+ds2/lib/libelf/elf_kind.30000644000000000000000000000422611361411226015142 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-9.2+ds2/lib/libelf/gelf_syminfo.c0000644000000000000000000000716310541424661016141 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-9.2+ds2/lib/libelf/gelf_getcap.30000644000000000000000000000656411361411226015636 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-9.2+ds2/lib/libelf/gelf_getrela.30000644000000000000000000000663311361411226016013 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-9.2+ds2/lib/libelf/elf_getdata.30000644000000000000000000001347712114717077015650 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-9.2+ds2/lib/libelf/elf_flag.c0000644000000000000000000000743110525402563015214 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-9.2+ds2/lib/libelf/gelf_move.c0000644000000000000000000000740710541424661015424 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-9.2+ds2/lib/libelf/elf_fill.30000644000000000000000000000362311361411226015143 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-9.2+ds2/lib/libelf/elf_next.c0000644000000000000000000000402610525402563015256 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-9.2+ds2/lib/libelf/elf_shstrndx.c0000644000000000000000000000445411421562272016162 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-9.2+ds2/lib/libelf/gelf_sym.c0000644000000000000000000000740010525402563015256 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-9.2+ds2/lib/libelf/elf_fill.c0000644000000000000000000000274310525402563015232 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-9.2+ds2/lib/libelf/elf_next.30000644000000000000000000000523611361411226015175 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-9.2+ds2/lib/libelf/elf_kind.c0000644000000000000000000000312110525402563015220 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-9.2+ds2/lib/libelf/gelf_phdr.c0000644000000000000000000001040011421533314015370 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-9.2+ds2/lib/libelf/libelf_extended.c0000644000000000000000000000634210543632736016601 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-9.2+ds2/lib/libelf/libelf_ehdr.c0000644000000000000000000001334711421545376015725 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-9.2+ds2/lib/libelf/elf_getarsym.c0000644000000000000000000000352210525402563016133 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-9.2+ds2/lib/libelf/elf_memory.c0000644000000000000000000000527110525402563015613 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-9.2+ds2/lib/libelf/elf_scn.c0000644000000000000000000001315011421545376015067 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-9.2+ds2/lib/libelf/libelf_checksum.c0000644000000000000000000000542410543632736016603 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-9.2+ds2/lib/libelf/gelf_getshdr.30000644000000000000000000000620411361411226016022 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-9.2+ds2/lib/libelf/gelf_dyn.c0000644000000000000000000000664310525402563015250 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-9.2+ds2/lib/libelf/elf_getarsym.30000644000000000000000000000713311361411226016050 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-9.2+ds2/lib/libelf/elf_getshstrndx.30000644000000000000000000000553311421562272016601 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. .Pp .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-9.2+ds2/lib/libelf/elf_memory.30000644000000000000000000000665711361411226015537 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-9.2+ds2/lib/libelf/gelf_getrel.30000644000000000000000000000656611361411226015657 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-9.2+ds2/lib/libelf/libelf_convert.m40000644000000000000000000005377711533156347016574 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-9.2+ds2/lib/libelf/libelf_phdr.c0000644000000000000000000000777011421545376015743 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-9.2+ds2/lib/libelf/elf_cntl.c0000644000000000000000000000345010525402563015240 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-9.2+ds2/lib/libelf/gelf_getclass.c0000644000000000000000000000276210525402563016261 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-9.2+ds2/lib/libelf/gelf_checksum.30000644000000000000000000000635011361411226016166 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-9.2+ds2/lib/libelf/gelf_update_ehdr.30000644000000000000000000000711711361411226016652 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-9.2+ds2/lib/libelf/gelf_getclass.30000644000000000000000000000371111361411226016167 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-9.2+ds2/lib/libelf/libelf_msize.m40000644000000000000000000000554311421542132016212 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-9.2+ds2/lib/libelf/gelf_checksum.c0000644000000000000000000000343510525402563016254 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-9.2+ds2/lib/libelf/elf_cntl.30000644000000000000000000000610311533536731015163 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-9.2+ds2/lib/libelf/gelf_rel.c0000644000000000000000000000730010762445046015235 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-9.2+ds2/lib/libelf/elf_hash.30000644000000000000000000000412511361411226015136 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-9.2+ds2/lib/libelf/elf_getshdrstrndx.30000644000000000000000000000511111421562272017117 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 .Os .Dt ELF_GETSHDRSTRNDX 3 .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. .Pp .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-9.2+ds2/lib/libelf/elf_update.c0000644000000000000000000005607212155137625015577 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-9.2+ds2/lib/libelf/elf_hash.c0000644000000000000000000000343410525402563015225 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-9.2+ds2/lib/libelf/elf_update.30000644000000000000000000002001311700744605015476 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-9.2+ds2/lib/libelf/libelf_fsize.m40000644000000000000000000001040611421547141016202 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-9.2+ds2/lib/libelf/gelf_shdr.c0000644000000000000000000000662011421533314015404 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-9.2+ds2/lib/libelf/elf_flagdata.30000644000000000000000000001110111361411226015746 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-9.2+ds2/lib/libelf/gelf_xlate.c0000644000000000000000000000503710525402563015567 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-9.2+ds2/lib/libelf/libelf_ar_util.c0000644000000000000000000001251411421567012016424 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-9.2+ds2/lib/libelf/elf_data.c0000644000000000000000000001426112114717077015220 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-9.2+ds2/lib/libelf/gelf.h0000644000000000000000000001166310573705232014403 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-9.2+ds2/lib/libelf/elf_rawfile.30000644000000000000000000000453111361411226015645 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-9.2+ds2/lib/libelf/elf_end.c0000644000000000000000000000464610525402563015056 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-9.2+ds2/lib/libelf/elf_getident.c0000644000000000000000000000367010525402563016107 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-9.2+ds2/lib/libelf/libelf.h0000644000000000000000000001675211421562272014725 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-9.2+ds2/lib/libelf/gelf_getsymshndx.30000644000000000000000000001007311361411226016736 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-9.2+ds2/lib/libelf/elf_getident.30000644000000000000000000000504511361411226016020 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-9.2+ds2/lib/libelf/elf_rawfile.c0000644000000000000000000000332410525402563015731 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-9.2+ds2/lib/libelf/elf_end.30000644000000000000000000000452711361411226014767 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-9.2+ds2/lib/libelf/elf_getshdrnum.30000644000000000000000000000473011421562272016402 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 .Os .Dt ELF_GETSHDRNUM 3 .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. .Pp .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-9.2+ds2/lib/libelf/gelf_getdyn.30000644000000000000000000000662511361411226015663 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-9.2+ds2/lib/libdevstat/0000755000000000000000000000000012244372436014215 5ustar freebsd-libs-9.2+ds2/lib/libdevstat/devstat.c0000644000000000000000000014167511546307207016047 0ustar /* * Copyright (c) 1997, 1998 Kenneth D. Merry. * 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. 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "devstat.h" int compute_stats(struct devstat *current, struct devstat *previous, long double etime, u_int64_t *total_bytes, u_int64_t *total_transfers, u_int64_t *total_blocks, long double *kb_per_transfer, long double *transfers_per_second, long double *mb_per_second, long double *blocks_per_second, long double *ms_per_transaction); typedef enum { DEVSTAT_ARG_NOTYPE, DEVSTAT_ARG_UINT64, DEVSTAT_ARG_LD, DEVSTAT_ARG_SKIP } devstat_arg_type; char devstat_errbuf[DEVSTAT_ERRBUF_SIZE]; /* * Table to match descriptive strings with device types. These are in * order from most common to least common to speed search time. */ struct devstat_match_table match_table[] = { {"da", DEVSTAT_TYPE_DIRECT, DEVSTAT_MATCH_TYPE}, {"cd", DEVSTAT_TYPE_CDROM, DEVSTAT_MATCH_TYPE}, {"scsi", DEVSTAT_TYPE_IF_SCSI, DEVSTAT_MATCH_IF}, {"ide", DEVSTAT_TYPE_IF_IDE, DEVSTAT_MATCH_IF}, {"other", DEVSTAT_TYPE_IF_OTHER, DEVSTAT_MATCH_IF}, {"worm", DEVSTAT_TYPE_WORM, DEVSTAT_MATCH_TYPE}, {"sa", DEVSTAT_TYPE_SEQUENTIAL,DEVSTAT_MATCH_TYPE}, {"pass", DEVSTAT_TYPE_PASS, DEVSTAT_MATCH_PASS}, {"optical", DEVSTAT_TYPE_OPTICAL, DEVSTAT_MATCH_TYPE}, {"array", DEVSTAT_TYPE_STORARRAY, DEVSTAT_MATCH_TYPE}, {"changer", DEVSTAT_TYPE_CHANGER, DEVSTAT_MATCH_TYPE}, {"scanner", DEVSTAT_TYPE_SCANNER, DEVSTAT_MATCH_TYPE}, {"printer", DEVSTAT_TYPE_PRINTER, DEVSTAT_MATCH_TYPE}, {"floppy", DEVSTAT_TYPE_FLOPPY, DEVSTAT_MATCH_TYPE}, {"proc", DEVSTAT_TYPE_PROCESSOR, DEVSTAT_MATCH_TYPE}, {"comm", DEVSTAT_TYPE_COMM, DEVSTAT_MATCH_TYPE}, {"enclosure", DEVSTAT_TYPE_ENCLOSURE, DEVSTAT_MATCH_TYPE}, {NULL, 0, 0} }; struct devstat_args { devstat_metric metric; devstat_arg_type argtype; } devstat_arg_list[] = { { DSM_NONE, DEVSTAT_ARG_NOTYPE }, { DSM_TOTAL_BYTES, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_BYTES_READ, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_BYTES_WRITE, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_TRANSFERS, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_TRANSFERS_READ, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_TRANSFERS_WRITE, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_TRANSFERS_OTHER, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_BLOCKS, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_BLOCKS_READ, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_BLOCKS_WRITE, DEVSTAT_ARG_UINT64 }, { DSM_KB_PER_TRANSFER, DEVSTAT_ARG_LD }, { DSM_KB_PER_TRANSFER_READ, DEVSTAT_ARG_LD }, { DSM_KB_PER_TRANSFER_WRITE, DEVSTAT_ARG_LD }, { DSM_TRANSFERS_PER_SECOND, DEVSTAT_ARG_LD }, { DSM_TRANSFERS_PER_SECOND_READ, DEVSTAT_ARG_LD }, { DSM_TRANSFERS_PER_SECOND_WRITE, DEVSTAT_ARG_LD }, { DSM_TRANSFERS_PER_SECOND_OTHER, DEVSTAT_ARG_LD }, { DSM_MB_PER_SECOND, DEVSTAT_ARG_LD }, { DSM_MB_PER_SECOND_READ, DEVSTAT_ARG_LD }, { DSM_MB_PER_SECOND_WRITE, DEVSTAT_ARG_LD }, { DSM_BLOCKS_PER_SECOND, DEVSTAT_ARG_LD }, { DSM_BLOCKS_PER_SECOND_READ, DEVSTAT_ARG_LD }, { DSM_BLOCKS_PER_SECOND_WRITE, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION_READ, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION_WRITE, DEVSTAT_ARG_LD }, { DSM_SKIP, DEVSTAT_ARG_SKIP }, { DSM_TOTAL_BYTES_FREE, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_TRANSFERS_FREE, DEVSTAT_ARG_UINT64 }, { DSM_TOTAL_BLOCKS_FREE, DEVSTAT_ARG_UINT64 }, { DSM_KB_PER_TRANSFER_FREE, DEVSTAT_ARG_LD }, { DSM_MB_PER_SECOND_FREE, DEVSTAT_ARG_LD }, { DSM_TRANSFERS_PER_SECOND_FREE, DEVSTAT_ARG_LD }, { DSM_BLOCKS_PER_SECOND_FREE, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION_OTHER, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION_FREE, DEVSTAT_ARG_LD }, { DSM_BUSY_PCT, DEVSTAT_ARG_LD }, { DSM_QUEUE_LENGTH, DEVSTAT_ARG_UINT64 }, }; static const char *namelist[] = { #define X_NUMDEVS 0 "_devstat_num_devs", #define X_GENERATION 1 "_devstat_generation", #define X_VERSION 2 "_devstat_version", #define X_DEVICE_STATQ 3 "_device_statq", #define X_END 4 }; /* * Local function declarations. */ static int compare_select(const void *arg1, const void *arg2); static int readkmem(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes); static int readkmem_nl(kvm_t *kd, const char *name, void *buf, size_t nbytes); static char *get_devstat_kvm(kvm_t *kd); #define KREADNL(kd, var, val) \ readkmem_nl(kd, namelist[var], &val, sizeof(val)) int devstat_getnumdevs(kvm_t *kd) { size_t numdevsize; int numdevs; numdevsize = sizeof(int); /* * Find out how many devices we have in the system. */ if (kd == NULL) { if (sysctlbyname("kern.devstat.numdevs", &numdevs, &numdevsize, NULL, 0) == -1) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error getting number of devices\n" "%s: %s", __func__, __func__, strerror(errno)); return(-1); } else return(numdevs); } else { if (KREADNL(kd, X_NUMDEVS, numdevs) == -1) return(-1); else return(numdevs); } } /* * This is an easy way to get the generation number, but the generation is * supplied in a more atmoic manner by the kern.devstat.all sysctl. * Because this generation sysctl is separate from the statistics sysctl, * the device list and the generation could change between the time that * this function is called and the device list is retreived. */ long devstat_getgeneration(kvm_t *kd) { size_t gensize; long generation; gensize = sizeof(long); /* * Get the current generation number. */ if (kd == NULL) { if (sysctlbyname("kern.devstat.generation", &generation, &gensize, NULL, 0) == -1) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error getting devstat generation\n%s: %s", __func__, __func__, strerror(errno)); return(-1); } else return(generation); } else { if (KREADNL(kd, X_GENERATION, generation) == -1) return(-1); else return(generation); } } /* * Get the current devstat version. The return value of this function * should be compared with DEVSTAT_VERSION, which is defined in * sys/devicestat.h. This will enable userland programs to determine * whether they are out of sync with the kernel. */ int devstat_getversion(kvm_t *kd) { size_t versize; int version; versize = sizeof(int); /* * Get the current devstat version. */ if (kd == NULL) { if (sysctlbyname("kern.devstat.version", &version, &versize, NULL, 0) == -1) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error getting devstat version\n%s: %s", __func__, __func__, strerror(errno)); return(-1); } else return(version); } else { if (KREADNL(kd, X_VERSION, version) == -1) return(-1); else return(version); } } /* * Check the devstat version we know about against the devstat version the * kernel knows about. If they don't match, print an error into the * devstat error buffer, and return -1. If they match, return 0. */ int devstat_checkversion(kvm_t *kd) { int buflen, res, retval = 0, version; version = devstat_getversion(kd); if (version != DEVSTAT_VERSION) { /* * If getversion() returns an error (i.e. -1), then it * has printed an error message in the buffer. Therefore, * we need to add a \n to the end of that message before we * print our own message in the buffer. */ if (version == -1) buflen = strlen(devstat_errbuf); else buflen = 0; res = snprintf(devstat_errbuf + buflen, DEVSTAT_ERRBUF_SIZE - buflen, "%s%s: userland devstat version %d is not " "the same as the kernel\n%s: devstat " "version %d\n", version == -1 ? "\n" : "", __func__, DEVSTAT_VERSION, __func__, version); if (res < 0) devstat_errbuf[buflen] = '\0'; buflen = strlen(devstat_errbuf); if (version < DEVSTAT_VERSION) res = snprintf(devstat_errbuf + buflen, DEVSTAT_ERRBUF_SIZE - buflen, "%s: libdevstat newer than kernel\n", __func__); else res = snprintf(devstat_errbuf + buflen, DEVSTAT_ERRBUF_SIZE - buflen, "%s: kernel newer than libdevstat\n", __func__); if (res < 0) devstat_errbuf[buflen] = '\0'; retval = -1; } return(retval); } /* * Get the current list of devices and statistics, and the current * generation number. * * Return values: * -1 -- error * 0 -- device list is unchanged * 1 -- device list has changed */ int devstat_getdevs(kvm_t *kd, struct statinfo *stats) { int error; size_t dssize; int oldnumdevs; long oldgeneration; int retval = 0; struct devinfo *dinfo; struct timespec ts; dinfo = stats->dinfo; if (dinfo == NULL) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: stats->dinfo was NULL", __func__); return(-1); } oldnumdevs = dinfo->numdevs; oldgeneration = dinfo->generation; clock_gettime(CLOCK_MONOTONIC, &ts); stats->snap_time = ts.tv_sec + ts.tv_nsec * 1e-9; if (kd == NULL) { /* If this is our first time through, mem_ptr will be null. */ if (dinfo->mem_ptr == NULL) { /* * Get the number of devices. If it's negative, it's an * error. Don't bother setting the error string, since * getnumdevs() has already done that for us. */ if ((dinfo->numdevs = devstat_getnumdevs(kd)) < 0) return(-1); /* * The kern.devstat.all sysctl returns the current * generation number, as well as all the devices. * So we need four bytes more. */ dssize = (dinfo->numdevs * sizeof(struct devstat)) + sizeof(long); dinfo->mem_ptr = (u_int8_t *)malloc(dssize); } else dssize = (dinfo->numdevs * sizeof(struct devstat)) + sizeof(long); /* * Request all of the devices. We only really allow for one * ENOMEM failure. It would, of course, be possible to just go * in a loop and keep reallocing the device structure until we * don't get ENOMEM back. I'm not sure it's worth it, though. * If devices are being added to the system that quickly, maybe * the user can just wait until all devices are added. */ for (;;) { error = sysctlbyname("kern.devstat.all", dinfo->mem_ptr, &dssize, NULL, 0); if (error != -1 || errno != EBUSY) break; } if (error == -1) { /* * If we get ENOMEM back, that means that there are * more devices now, so we need to allocate more * space for the device array. */ if (errno == ENOMEM) { /* * No need to set the error string here, * devstat_getnumdevs() will do that if it fails. */ if ((dinfo->numdevs = devstat_getnumdevs(kd)) < 0) return(-1); dssize = (dinfo->numdevs * sizeof(struct devstat)) + sizeof(long); dinfo->mem_ptr = (u_int8_t *) realloc(dinfo->mem_ptr, dssize); if ((error = sysctlbyname("kern.devstat.all", dinfo->mem_ptr, &dssize, NULL, 0)) == -1) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error getting device " "stats\n%s: %s", __func__, __func__, strerror(errno)); return(-1); } } else { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error getting device stats\n" "%s: %s", __func__, __func__, strerror(errno)); return(-1); } } } else { /* * This is of course non-atomic, but since we are working * on a core dump, the generation is unlikely to change */ if ((dinfo->numdevs = devstat_getnumdevs(kd)) == -1) return(-1); if ((dinfo->mem_ptr = (u_int8_t *)get_devstat_kvm(kd)) == NULL) return(-1); } /* * The sysctl spits out the generation as the first four bytes, * then all of the device statistics structures. */ dinfo->generation = *(long *)dinfo->mem_ptr; /* * If the generation has changed, and if the current number of * devices is not the same as the number of devices recorded in the * devinfo structure, it is likely that the device list has shrunk. * The reason that it is likely that the device list has shrunk in * this case is that if the device list has grown, the sysctl above * will return an ENOMEM error, and we will reset the number of * devices and reallocate the device array. If the second sysctl * fails, we will return an error and therefore never get to this * point. If the device list has shrunk, the sysctl will not * return an error since we have more space allocated than is * necessary. So, in the shrinkage case, we catch it here and * reallocate the array so that we don't use any more space than is * necessary. */ if (oldgeneration != dinfo->generation) { if (devstat_getnumdevs(kd) != dinfo->numdevs) { if ((dinfo->numdevs = devstat_getnumdevs(kd)) < 0) return(-1); dssize = (dinfo->numdevs * sizeof(struct devstat)) + sizeof(long); dinfo->mem_ptr = (u_int8_t *)realloc(dinfo->mem_ptr, dssize); } retval = 1; } dinfo->devices = (struct devstat *)(dinfo->mem_ptr + sizeof(long)); return(retval); } /* * selectdevs(): * * Devices are selected/deselected based upon the following criteria: * - devices specified by the user on the command line * - devices matching any device type expressions given on the command line * - devices with the highest I/O, if 'top' mode is enabled * - the first n unselected devices in the device list, if maxshowdevs * devices haven't already been selected and if the user has not * specified any devices on the command line and if we're in "add" mode. * * Input parameters: * - device selection list (dev_select) * - current number of devices selected (num_selected) * - total number of devices in the selection list (num_selections) * - devstat generation as of the last time selectdevs() was called * (select_generation) * - current devstat generation (current_generation) * - current list of devices and statistics (devices) * - number of devices in the current device list (numdevs) * - compiled version of the command line device type arguments (matches) * - This is optional. If the number of devices is 0, this will be ignored. * - The matching code pays attention to the current selection mode. So * if you pass in a matching expression, it will be evaluated based * upon the selection mode that is passed in. See below for details. * - number of device type matching expressions (num_matches) * - Set to 0 to disable the matching code. * - list of devices specified on the command line by the user (dev_selections) * - number of devices selected on the command line by the user * (num_dev_selections) * - Our selection mode. There are four different selection modes: * - add mode. (DS_SELECT_ADD) Any devices matching devices explicitly * selected by the user or devices matching a pattern given by the * user will be selected in addition to devices that are already * selected. Additional devices will be selected, up to maxshowdevs * number of devices. * - only mode. (DS_SELECT_ONLY) Only devices matching devices * explicitly given by the user or devices matching a pattern * given by the user will be selected. No other devices will be * selected. * - addonly mode. (DS_SELECT_ADDONLY) This is similar to add and * only. Basically, this will not de-select any devices that are * current selected, as only mode would, but it will also not * gratuitously select up to maxshowdevs devices as add mode would. * - remove mode. (DS_SELECT_REMOVE) Any devices matching devices * explicitly selected by the user or devices matching a pattern * given by the user will be de-selected. * - maximum number of devices we can select (maxshowdevs) * - flag indicating whether or not we're in 'top' mode (perf_select) * * Output data: * - the device selection list may be modified and passed back out * - the number of devices selected and the total number of items in the * device selection list may be changed * - the selection generation may be changed to match the current generation * * Return values: * -1 -- error * 0 -- selected devices are unchanged * 1 -- selected devices changed */ int devstat_selectdevs(struct device_selection **dev_select, int *num_selected, int *num_selections, long *select_generation, long current_generation, struct devstat *devices, int numdevs, struct devstat_match *matches, int num_matches, char **dev_selections, int num_dev_selections, devstat_select_mode select_mode, int maxshowdevs, int perf_select) { int i, j, k; int init_selections = 0, init_selected_var = 0; struct device_selection *old_dev_select = NULL; int old_num_selections = 0, old_num_selected; int selection_number = 0; int changed = 0, found = 0; if ((dev_select == NULL) || (devices == NULL) || (numdevs < 0)) return(-1); /* * We always want to make sure that we have as many dev_select * entries as there are devices. */ /* * In this case, we haven't selected devices before. */ if (*dev_select == NULL) { *dev_select = (struct device_selection *)malloc(numdevs * sizeof(struct device_selection)); *select_generation = current_generation; init_selections = 1; changed = 1; /* * In this case, we have selected devices before, but the device * list has changed since we last selected devices, so we need to * either enlarge or reduce the size of the device selection list. */ } else if (*num_selections != numdevs) { *dev_select = (struct device_selection *)realloc(*dev_select, numdevs * sizeof(struct device_selection)); *select_generation = current_generation; init_selections = 1; /* * In this case, we've selected devices before, and the selection * list is the same size as it was the last time, but the device * list has changed. */ } else if (*select_generation < current_generation) { *select_generation = current_generation; init_selections = 1; } /* * If we're in "only" mode, we want to clear out the selected * variable since we're going to select exactly what the user wants * this time through. */ if (select_mode == DS_SELECT_ONLY) init_selected_var = 1; /* * In all cases, we want to back up the number of selected devices. * It is a quick and accurate way to determine whether the selected * devices have changed. */ old_num_selected = *num_selected; /* * We want to make a backup of the current selection list if * the list of devices has changed, or if we're in performance * selection mode. In both cases, we don't want to make a backup * if we already know for sure that the list will be different. * This is certainly the case if this is our first time through the * selection code. */ if (((init_selected_var != 0) || (init_selections != 0) || (perf_select != 0)) && (changed == 0)){ old_dev_select = (struct device_selection *)malloc( *num_selections * sizeof(struct device_selection)); old_num_selections = *num_selections; bcopy(*dev_select, old_dev_select, sizeof(struct device_selection) * *num_selections); } if (init_selections != 0) { bzero(*dev_select, sizeof(struct device_selection) * numdevs); for (i = 0; i < numdevs; i++) { (*dev_select)[i].device_number = devices[i].device_number; strncpy((*dev_select)[i].device_name, devices[i].device_name, DEVSTAT_NAME_LEN); (*dev_select)[i].device_name[DEVSTAT_NAME_LEN - 1]='\0'; (*dev_select)[i].unit_number = devices[i].unit_number; (*dev_select)[i].position = i; } *num_selections = numdevs; } else if (init_selected_var != 0) { for (i = 0; i < numdevs; i++) (*dev_select)[i].selected = 0; } /* we haven't gotten around to selecting anything yet.. */ if ((select_mode == DS_SELECT_ONLY) || (init_selections != 0) || (init_selected_var != 0)) *num_selected = 0; /* * Look through any devices the user specified on the command line * and see if they match known devices. If so, select them. */ for (i = 0; (i < *num_selections) && (num_dev_selections > 0); i++) { char tmpstr[80]; snprintf(tmpstr, sizeof(tmpstr), "%s%d", (*dev_select)[i].device_name, (*dev_select)[i].unit_number); for (j = 0; j < num_dev_selections; j++) { if (strcmp(tmpstr, dev_selections[j]) == 0) { /* * Here we do different things based on the * mode we're in. If we're in add or * addonly mode, we only select this device * if it hasn't already been selected. * Otherwise, we would be unnecessarily * changing the selection order and * incrementing the selection count. If * we're in only mode, we unconditionally * select this device, since in only mode * any previous selections are erased and * manually specified devices are the first * ones to be selected. If we're in remove * mode, we de-select the specified device and * decrement the selection count. */ switch(select_mode) { case DS_SELECT_ADD: case DS_SELECT_ADDONLY: if ((*dev_select)[i].selected) break; /* FALLTHROUGH */ case DS_SELECT_ONLY: (*dev_select)[i].selected = ++selection_number; (*num_selected)++; break; case DS_SELECT_REMOVE: (*dev_select)[i].selected = 0; (*num_selected)--; /* * This isn't passed back out, we * just use it to keep track of * how many devices we've removed. */ num_dev_selections--; break; } break; } } } /* * Go through the user's device type expressions and select devices * accordingly. We only do this if the number of devices already * selected is less than the maximum number we can show. */ for (i = 0; (i < num_matches) && (*num_selected < maxshowdevs); i++) { /* We should probably indicate some error here */ if ((matches[i].match_fields == DEVSTAT_MATCH_NONE) || (matches[i].num_match_categories <= 0)) continue; for (j = 0; j < numdevs; j++) { int num_match_categories; num_match_categories = matches[i].num_match_categories; /* * Determine whether or not the current device * matches the given matching expression. This if * statement consists of three components: * - the device type check * - the device interface check * - the passthrough check * If a the matching test is successful, it * decrements the number of matching categories, * and if we've reached the last element that * needed to be matched, the if statement succeeds. * */ if ((((matches[i].match_fields & DEVSTAT_MATCH_TYPE)!=0) && ((devices[j].device_type & DEVSTAT_TYPE_MASK) == (matches[i].device_type & DEVSTAT_TYPE_MASK)) &&(((matches[i].match_fields & DEVSTAT_MATCH_PASS)!=0) || (((matches[i].match_fields & DEVSTAT_MATCH_PASS) == 0) && ((devices[j].device_type & DEVSTAT_TYPE_PASS) == 0))) && (--num_match_categories == 0)) || (((matches[i].match_fields & DEVSTAT_MATCH_IF) != 0) && ((devices[j].device_type & DEVSTAT_TYPE_IF_MASK) == (matches[i].device_type & DEVSTAT_TYPE_IF_MASK)) &&(((matches[i].match_fields & DEVSTAT_MATCH_PASS)!=0) || (((matches[i].match_fields & DEVSTAT_MATCH_PASS) == 0) && ((devices[j].device_type & DEVSTAT_TYPE_PASS) == 0))) && (--num_match_categories == 0)) || (((matches[i].match_fields & DEVSTAT_MATCH_PASS)!=0) && ((devices[j].device_type & DEVSTAT_TYPE_PASS) != 0) && (--num_match_categories == 0))) { /* * This is probably a non-optimal solution * to the problem that the devices in the * device list will not be in the same * order as the devices in the selection * array. */ for (k = 0; k < numdevs; k++) { if ((*dev_select)[k].position == j) { found = 1; break; } } /* * There shouldn't be a case where a device * in the device list is not in the * selection list...but it could happen. */ if (found != 1) { fprintf(stderr, "selectdevs: couldn't" " find %s%d in selection " "list\n", devices[j].device_name, devices[j].unit_number); break; } /* * We do different things based upon the * mode we're in. If we're in add or only * mode, we go ahead and select this device * if it hasn't already been selected. If * it has already been selected, we leave * it alone so we don't mess up the * selection ordering. Manually specified * devices have already been selected, and * they have higher priority than pattern * matched devices. If we're in remove * mode, we de-select the given device and * decrement the selected count. */ switch(select_mode) { case DS_SELECT_ADD: case DS_SELECT_ADDONLY: case DS_SELECT_ONLY: if ((*dev_select)[k].selected != 0) break; (*dev_select)[k].selected = ++selection_number; (*num_selected)++; break; case DS_SELECT_REMOVE: (*dev_select)[k].selected = 0; (*num_selected)--; break; } } } } /* * Here we implement "top" mode. Devices are sorted in the * selection array based on two criteria: whether or not they are * selected (not selection number, just the fact that they are * selected!) and the number of bytes in the "bytes" field of the * selection structure. The bytes field generally must be kept up * by the user. In the future, it may be maintained by library * functions, but for now the user has to do the work. * * At first glance, it may seem wrong that we don't go through and * select every device in the case where the user hasn't specified * any devices or patterns. In fact, though, it won't make any * difference in the device sorting. In that particular case (i.e. * when we're in "add" or "only" mode, and the user hasn't * specified anything) the first time through no devices will be * selected, so the only criterion used to sort them will be their * performance. The second time through, and every time thereafter, * all devices will be selected, so again selection won't matter. */ if (perf_select != 0) { /* Sort the device array by throughput */ qsort(*dev_select, *num_selections, sizeof(struct device_selection), compare_select); if (*num_selected == 0) { /* * Here we select every device in the array, if it * isn't already selected. Because the 'selected' * variable in the selection array entries contains * the selection order, the devstats routine can show * the devices that were selected first. */ for (i = 0; i < *num_selections; i++) { if ((*dev_select)[i].selected == 0) { (*dev_select)[i].selected = ++selection_number; (*num_selected)++; } } } else { selection_number = 0; for (i = 0; i < *num_selections; i++) { if ((*dev_select)[i].selected != 0) { (*dev_select)[i].selected = ++selection_number; } } } } /* * If we're in the "add" selection mode and if we haven't already * selected maxshowdevs number of devices, go through the array and * select any unselected devices. If we're in "only" mode, we * obviously don't want to select anything other than what the user * specifies. If we're in "remove" mode, it probably isn't a good * idea to go through and select any more devices, since we might * end up selecting something that the user wants removed. Through * more complicated logic, we could actually figure this out, but * that would probably require combining this loop with the various * selections loops above. */ if ((select_mode == DS_SELECT_ADD) && (*num_selected < maxshowdevs)) { for (i = 0; i < *num_selections; i++) if ((*dev_select)[i].selected == 0) { (*dev_select)[i].selected = ++selection_number; (*num_selected)++; } } /* * Look at the number of devices that have been selected. If it * has changed, set the changed variable. Otherwise, if we've * made a backup of the selection list, compare it to the current * selection list to see if the selected devices have changed. */ if ((changed == 0) && (old_num_selected != *num_selected)) changed = 1; else if ((changed == 0) && (old_dev_select != NULL)) { /* * Now we go through the selection list and we look at * it three different ways. */ for (i = 0; (i < *num_selections) && (changed == 0) && (i < old_num_selections); i++) { /* * If the device at index i in both the new and old * selection arrays has the same device number and * selection status, it hasn't changed. We * continue on to the next index. */ if (((*dev_select)[i].device_number == old_dev_select[i].device_number) && ((*dev_select)[i].selected == old_dev_select[i].selected)) continue; /* * Now, if we're still going through the if * statement, the above test wasn't true. So we * check here to see if the device at index i in * the current array is the same as the device at * index i in the old array. If it is, that means * that its selection number has changed. Set * changed to 1 and exit the loop. */ else if ((*dev_select)[i].device_number == old_dev_select[i].device_number) { changed = 1; break; } /* * If we get here, then the device at index i in * the current array isn't the same device as the * device at index i in the old array. */ else { found = 0; /* * Search through the old selection array * looking for a device with the same * device number as the device at index i * in the current array. If the selection * status is the same, then we mark it as * found. If the selection status isn't * the same, we break out of the loop. * Since found isn't set, changed will be * set to 1 below. */ for (j = 0; j < old_num_selections; j++) { if (((*dev_select)[i].device_number == old_dev_select[j].device_number) && ((*dev_select)[i].selected == old_dev_select[j].selected)){ found = 1; break; } else if ((*dev_select)[i].device_number == old_dev_select[j].device_number) break; } if (found == 0) changed = 1; } } } if (old_dev_select != NULL) free(old_dev_select); return(changed); } /* * Comparison routine for qsort() above. Note that the comparison here is * backwards -- generally, it should return a value to indicate whether * arg1 is <, =, or > arg2. Instead, it returns the opposite. The reason * it returns the opposite is so that the selection array will be sorted in * order of decreasing performance. We sort on two parameters. The first * sort key is whether or not one or the other of the devices in question * has been selected. If one of them has, and the other one has not, the * selected device is automatically more important than the unselected * device. If neither device is selected, we judge the devices based upon * performance. */ static int compare_select(const void *arg1, const void *arg2) { if ((((const struct device_selection *)arg1)->selected) && (((const struct device_selection *)arg2)->selected == 0)) return(-1); else if ((((const struct device_selection *)arg1)->selected == 0) && (((const struct device_selection *)arg2)->selected)) return(1); else if (((const struct device_selection *)arg2)->bytes < ((const struct device_selection *)arg1)->bytes) return(-1); else if (((const struct device_selection *)arg2)->bytes > ((const struct device_selection *)arg1)->bytes) return(1); else return(0); } /* * Take a string with the general format "arg1,arg2,arg3", and build a * device matching expression from it. */ int devstat_buildmatch(char *match_str, struct devstat_match **matches, int *num_matches) { char *tstr[5]; char **tempstr; int num_args; int i, j; /* We can't do much without a string to parse */ if (match_str == NULL) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: no match expression", __func__); return(-1); } /* * Break the (comma delimited) input string out into separate strings. */ for (tempstr = tstr, num_args = 0; (*tempstr = strsep(&match_str, ",")) != NULL && (num_args < 5);) if (**tempstr != '\0') { num_args++; if (++tempstr >= &tstr[5]) break; } /* The user gave us too many type arguments */ if (num_args > 3) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: too many type arguments", __func__); return(-1); } /* * Since you can't realloc a pointer that hasn't been malloced * first, we malloc first and then realloc. */ if (*num_matches == 0) *matches = (struct devstat_match *)malloc( sizeof(struct devstat_match)); else *matches = (struct devstat_match *)realloc(*matches, sizeof(struct devstat_match) * (*num_matches + 1)); /* Make sure the current entry is clear */ bzero(&matches[0][*num_matches], sizeof(struct devstat_match)); /* * Step through the arguments the user gave us and build a device * matching expression from them. */ for (i = 0; i < num_args; i++) { char *tempstr2, *tempstr3; /* * Get rid of leading white space. */ tempstr2 = tstr[i]; while (isspace(*tempstr2) && (*tempstr2 != '\0')) tempstr2++; /* * Get rid of trailing white space. */ tempstr3 = &tempstr2[strlen(tempstr2) - 1]; while ((*tempstr3 != '\0') && (tempstr3 > tempstr2) && (isspace(*tempstr3))) { *tempstr3 = '\0'; tempstr3--; } /* * Go through the match table comparing the user's * arguments to known device types, interfaces, etc. */ for (j = 0; match_table[j].match_str != NULL; j++) { /* * We do case-insensitive matching, in case someone * wants to enter "SCSI" instead of "scsi" or * something like that. Only compare as many * characters as are in the string in the match * table. This should help if someone tries to use * a super-long match expression. */ if (strncasecmp(tempstr2, match_table[j].match_str, strlen(match_table[j].match_str)) == 0) { /* * Make sure the user hasn't specified two * items of the same type, like "da" and * "cd". One device cannot be both. */ if (((*matches)[*num_matches].match_fields & match_table[j].match_field) != 0) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: cannot have more than " "one match item in a single " "category", __func__); return(-1); } /* * If we've gotten this far, we have a * winner. Set the appropriate fields in * the match entry. */ (*matches)[*num_matches].match_fields |= match_table[j].match_field; (*matches)[*num_matches].device_type |= match_table[j].type; (*matches)[*num_matches].num_match_categories++; break; } } /* * We should have found a match in the above for loop. If * not, that means the user entered an invalid device type * or interface. */ if ((*matches)[*num_matches].num_match_categories != (i + 1)) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: unknown match item \"%s\"", __func__, tstr[i]); return(-1); } } (*num_matches)++; return(0); } /* * Compute a number of device statistics. Only one field is mandatory, and * that is "current". Everything else is optional. The caller passes in * pointers to variables to hold the various statistics he desires. If he * doesn't want a particular staistic, he should pass in a NULL pointer. * Return values: * 0 -- success * -1 -- failure */ int compute_stats(struct devstat *current, struct devstat *previous, long double etime, u_int64_t *total_bytes, u_int64_t *total_transfers, u_int64_t *total_blocks, long double *kb_per_transfer, long double *transfers_per_second, long double *mb_per_second, long double *blocks_per_second, long double *ms_per_transaction) { return(devstat_compute_statistics(current, previous, etime, total_bytes ? DSM_TOTAL_BYTES : DSM_SKIP, total_bytes, total_transfers ? DSM_TOTAL_TRANSFERS : DSM_SKIP, total_transfers, total_blocks ? DSM_TOTAL_BLOCKS : DSM_SKIP, total_blocks, kb_per_transfer ? DSM_KB_PER_TRANSFER : DSM_SKIP, kb_per_transfer, transfers_per_second ? DSM_TRANSFERS_PER_SECOND : DSM_SKIP, transfers_per_second, mb_per_second ? DSM_MB_PER_SECOND : DSM_SKIP, mb_per_second, blocks_per_second ? DSM_BLOCKS_PER_SECOND : DSM_SKIP, blocks_per_second, ms_per_transaction ? DSM_MS_PER_TRANSACTION : DSM_SKIP, ms_per_transaction, DSM_NONE)); } /* This is 1/2^64 */ #define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-20 long double devstat_compute_etime(struct bintime *cur_time, struct bintime *prev_time) { long double etime; etime = cur_time->sec; etime += cur_time->frac * BINTIME_SCALE; if (prev_time != NULL) { etime -= prev_time->sec; etime -= prev_time->frac * BINTIME_SCALE; } return(etime); } #define DELTA(field, index) \ (current->field[(index)] - (previous ? previous->field[(index)] : 0)) #define DELTA_T(field) \ devstat_compute_etime(¤t->field, \ (previous ? &previous->field : NULL)) int devstat_compute_statistics(struct devstat *current, struct devstat *previous, long double etime, ...) { u_int64_t totalbytes, totalbytesread, totalbyteswrite, totalbytesfree; u_int64_t totaltransfers, totaltransfersread, totaltransferswrite; u_int64_t totaltransfersother, totalblocks, totalblocksread; u_int64_t totalblockswrite, totaltransfersfree, totalblocksfree; va_list ap; devstat_metric metric; u_int64_t *destu64; long double *destld; int retval, i; retval = 0; /* * current is the only mandatory field. */ if (current == NULL) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: current stats structure was NULL", __func__); return(-1); } totalbytesread = DELTA(bytes, DEVSTAT_READ); totalbyteswrite = DELTA(bytes, DEVSTAT_WRITE); totalbytesfree = DELTA(bytes, DEVSTAT_FREE); totalbytes = totalbytesread + totalbyteswrite + totalbytesfree; totaltransfersread = DELTA(operations, DEVSTAT_READ); totaltransferswrite = DELTA(operations, DEVSTAT_WRITE); totaltransfersother = DELTA(operations, DEVSTAT_NO_DATA); totaltransfersfree = DELTA(operations, DEVSTAT_FREE); totaltransfers = totaltransfersread + totaltransferswrite + totaltransfersother + totaltransfersfree; totalblocks = totalbytes; totalblocksread = totalbytesread; totalblockswrite = totalbyteswrite; totalblocksfree = totalbytesfree; if (current->block_size > 0) { totalblocks /= current->block_size; totalblocksread /= current->block_size; totalblockswrite /= current->block_size; totalblocksfree /= current->block_size; } else { totalblocks /= 512; totalblocksread /= 512; totalblockswrite /= 512; totalblocksfree /= 512; } va_start(ap, etime); while ((metric = (devstat_metric)va_arg(ap, devstat_metric)) != 0) { if (metric == DSM_NONE) break; if (metric >= DSM_MAX) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: metric %d is out of range", __func__, metric); retval = -1; goto bailout; } switch (devstat_arg_list[metric].argtype) { case DEVSTAT_ARG_UINT64: destu64 = (u_int64_t *)va_arg(ap, u_int64_t *); break; case DEVSTAT_ARG_LD: destld = (long double *)va_arg(ap, long double *); break; case DEVSTAT_ARG_SKIP: destld = (long double *)va_arg(ap, long double *); break; default: retval = -1; goto bailout; break; /* NOTREACHED */ } if (devstat_arg_list[metric].argtype == DEVSTAT_ARG_SKIP) continue; switch (metric) { case DSM_TOTAL_BYTES: *destu64 = totalbytes; break; case DSM_TOTAL_BYTES_READ: *destu64 = totalbytesread; break; case DSM_TOTAL_BYTES_WRITE: *destu64 = totalbyteswrite; break; case DSM_TOTAL_BYTES_FREE: *destu64 = totalbytesfree; break; case DSM_TOTAL_TRANSFERS: *destu64 = totaltransfers; break; case DSM_TOTAL_TRANSFERS_READ: *destu64 = totaltransfersread; break; case DSM_TOTAL_TRANSFERS_WRITE: *destu64 = totaltransferswrite; break; case DSM_TOTAL_TRANSFERS_FREE: *destu64 = totaltransfersfree; break; case DSM_TOTAL_TRANSFERS_OTHER: *destu64 = totaltransfersother; break; case DSM_TOTAL_BLOCKS: *destu64 = totalblocks; break; case DSM_TOTAL_BLOCKS_READ: *destu64 = totalblocksread; break; case DSM_TOTAL_BLOCKS_WRITE: *destu64 = totalblockswrite; break; case DSM_TOTAL_BLOCKS_FREE: *destu64 = totalblocksfree; break; case DSM_KB_PER_TRANSFER: *destld = totalbytes; *destld /= 1024; if (totaltransfers > 0) *destld /= totaltransfers; else *destld = 0.0; break; case DSM_KB_PER_TRANSFER_READ: *destld = totalbytesread; *destld /= 1024; if (totaltransfersread > 0) *destld /= totaltransfersread; else *destld = 0.0; break; case DSM_KB_PER_TRANSFER_WRITE: *destld = totalbyteswrite; *destld /= 1024; if (totaltransferswrite > 0) *destld /= totaltransferswrite; else *destld = 0.0; break; case DSM_KB_PER_TRANSFER_FREE: *destld = totalbytesfree; *destld /= 1024; if (totaltransfersfree > 0) *destld /= totaltransfersfree; else *destld = 0.0; break; case DSM_TRANSFERS_PER_SECOND: if (etime > 0.0) { *destld = totaltransfers; *destld /= etime; } else *destld = 0.0; break; case DSM_TRANSFERS_PER_SECOND_READ: if (etime > 0.0) { *destld = totaltransfersread; *destld /= etime; } else *destld = 0.0; break; case DSM_TRANSFERS_PER_SECOND_WRITE: if (etime > 0.0) { *destld = totaltransferswrite; *destld /= etime; } else *destld = 0.0; break; case DSM_TRANSFERS_PER_SECOND_FREE: if (etime > 0.0) { *destld = totaltransfersfree; *destld /= etime; } else *destld = 0.0; break; case DSM_TRANSFERS_PER_SECOND_OTHER: if (etime > 0.0) { *destld = totaltransfersother; *destld /= etime; } else *destld = 0.0; break; case DSM_MB_PER_SECOND: *destld = totalbytes; *destld /= 1024 * 1024; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_MB_PER_SECOND_READ: *destld = totalbytesread; *destld /= 1024 * 1024; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_MB_PER_SECOND_WRITE: *destld = totalbyteswrite; *destld /= 1024 * 1024; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_MB_PER_SECOND_FREE: *destld = totalbytesfree; *destld /= 1024 * 1024; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_BLOCKS_PER_SECOND: *destld = totalblocks; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_BLOCKS_PER_SECOND_READ: *destld = totalblocksread; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_BLOCKS_PER_SECOND_WRITE: *destld = totalblockswrite; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; case DSM_BLOCKS_PER_SECOND_FREE: *destld = totalblocksfree; if (etime > 0.0) *destld /= etime; else *destld = 0.0; break; /* * This calculation is somewhat bogus. It simply divides * the elapsed time by the total number of transactions * completed. While that does give the caller a good * picture of the average rate of transaction completion, * it doesn't necessarily give the caller a good view of * how long transactions took to complete on average. * Those two numbers will be different for a device that * can handle more than one transaction at a time. e.g. * SCSI disks doing tagged queueing. * * The only way to accurately determine the real average * time per transaction would be to compute and store the * time on a per-transaction basis. That currently isn't * done in the kernel, and would only be desireable if it * could be implemented in a somewhat non-intrusive and high * performance way. */ case DSM_MS_PER_TRANSACTION: if (totaltransfers > 0) { *destld = 0; for (i = 0; i < DEVSTAT_N_TRANS_FLAGS; i++) *destld += DELTA_T(duration[i]); *destld /= totaltransfers; *destld *= 1000; } else *destld = 0.0; break; /* * As above, these next two really only give the average * rate of completion for read and write transactions, not * the average time the transaction took to complete. */ case DSM_MS_PER_TRANSACTION_READ: if (totaltransfersread > 0) { *destld = DELTA_T(duration[DEVSTAT_READ]); *destld /= totaltransfersread; *destld *= 1000; } else *destld = 0.0; break; case DSM_MS_PER_TRANSACTION_WRITE: if (totaltransferswrite > 0) { *destld = DELTA_T(duration[DEVSTAT_WRITE]); *destld /= totaltransferswrite; *destld *= 1000; } else *destld = 0.0; break; case DSM_MS_PER_TRANSACTION_FREE: if (totaltransfersfree > 0) { *destld = DELTA_T(duration[DEVSTAT_FREE]); *destld /= totaltransfersfree; *destld *= 1000; } else *destld = 0.0; break; case DSM_MS_PER_TRANSACTION_OTHER: if (totaltransfersother > 0) { *destld = DELTA_T(duration[DEVSTAT_NO_DATA]); *destld /= totaltransfersother; *destld *= 1000; } else *destld = 0.0; break; case DSM_BUSY_PCT: *destld = DELTA_T(busy_time); if (*destld < 0) *destld = 0; *destld /= etime; *destld *= 100; if (*destld < 0) *destld = 0; break; case DSM_QUEUE_LENGTH: *destu64 = current->start_count - current->end_count; break; /* * XXX: comment out the default block to see if any case's are missing. */ #if 1 default: /* * This shouldn't happen, since we should have * caught any out of range metrics at the top of * the loop. */ snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: unknown metric %d", __func__, metric); retval = -1; goto bailout; break; /* NOTREACHED */ #endif } } bailout: va_end(ap); return(retval); } static int readkmem(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes) { if (kvm_read(kd, addr, buf, nbytes) == -1) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error reading value (kvm_read): %s", __func__, kvm_geterr(kd)); return(-1); } return(0); } static int readkmem_nl(kvm_t *kd, const char *name, void *buf, size_t nbytes) { struct nlist nl[2]; nl[0].n_name = (char *)name; nl[1].n_name = NULL; if (kvm_nlist(kd, nl) == -1) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: error getting name list (kvm_nlist): %s", __func__, kvm_geterr(kd)); return(-1); } return(readkmem(kd, nl[0].n_value, buf, nbytes)); } /* * This duplicates the functionality of the kernel sysctl handler for poking * through crash dumps. */ static char * get_devstat_kvm(kvm_t *kd) { int i, wp; long gen; struct devstat *nds; struct devstat ds; struct devstatlist dhead; int num_devs; char *rv = NULL; if ((num_devs = devstat_getnumdevs(kd)) <= 0) return(NULL); if (KREADNL(kd, X_DEVICE_STATQ, dhead) == -1) return(NULL); nds = STAILQ_FIRST(&dhead); if ((rv = malloc(sizeof(gen))) == NULL) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: out of memory (initial malloc failed)", __func__); return(NULL); } gen = devstat_getgeneration(kd); memcpy(rv, &gen, sizeof(gen)); wp = sizeof(gen); /* * Now push out all the devices. */ for (i = 0; (nds != NULL) && (i < num_devs); nds = STAILQ_NEXT(nds, dev_links), i++) { if (readkmem(kd, (long)nds, &ds, sizeof(ds)) == -1) { free(rv); return(NULL); } nds = &ds; rv = (char *)reallocf(rv, sizeof(gen) + sizeof(ds) * (i + 1)); if (rv == NULL) { snprintf(devstat_errbuf, sizeof(devstat_errbuf), "%s: out of memory (malloc failed)", __func__); return(NULL); } memcpy(rv + wp, &ds, sizeof(ds)); wp += sizeof(ds); } return(rv); } freebsd-libs-9.2+ds2/lib/libdevstat/devstat.30000644000000000000000000004507311426052171015754 0ustar .\" .\" Copyright (c) 1998, 1999, 2001 Kenneth D. Merry. .\" 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. 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$ .\" .Dd March 18, 2003 .Dt DEVSTAT 3 .Os .Sh NAME .Nm devstat , .Nm devstat_getnumdevs , .Nm devstat_getgeneration , .Nm devstat_getversion , .Nm devstat_checkversion , .Nm devstat_getdevs , .Nm devstat_selectdevs , .Nm devstat_buildmatch , .Nm devstat_compute_statistics , .Nm devstat_compute_etime .Nd device statistics utility library .Sh LIBRARY .Lb libdevstat .Sh SYNOPSIS .In devstat.h .Ft int .Fn devstat_getnumdevs "kvm_t *kd" .Ft long .Fn devstat_getgeneration "kvm_t *kd" .Ft int .Fn devstat_getversion "kvm_t *kd" .Ft int .Fn devstat_checkversion "kvm_t *kd" .Ft int .Fn devstat_getdevs "kvm_t *kd" "struct statinfo *stats" .Ft int .Fo devstat_selectdevs .Fa "struct device_selection **dev_select" .Fa "int *num_selected" .Fa "int *num_selections" .Fa "long *select_generation" .Fa "long current_generation" .Fa "struct devstat *devices" .Fa "int numdevs" .Fa "struct devstat_match *matches" .Fa "int num_matches" .Fa "char **dev_selections" .Fa "int num_dev_selections" .Fa "devstat_select_mode select_mode" .Fa "int maxshowdevs" .Fa "int perf_select" .Fc .Ft int .Fo devstat_buildmatch .Fa "char *match_str" .Fa "struct devstat_match **matches" .Fa "int *num_matches" .Fc .Ft int .Fo devstat_compute_statistics .Fa "struct devstat *current" .Fa "struct devstat *previous" .Fa "long double etime" .Fa "..." .Fc .Ft "long double" .Fo devstat_compute_etime .Fa "struct bintime *cur_time" .Fa "struct bintime *prev_time" .Fc .Sh DESCRIPTION The .Nm library is a library of helper functions for dealing with the kernel .Xr devstat 9 interface, which is accessible to users via .Xr sysctl 3 and .Xr kvm 3 . All functions that take a .Vt "kvm_t *" as first argument can be passed .Dv NULL instead of a kvm handle as this argument, which causes the data to be read via .Xr sysctl 3 . Otherwise, it is read via .Xr kvm 3 using the supplied handle. The .Fn devstat_checkversion function should be called with each kvm handle that is going to be used (or with .Dv NULL if .Xr sysctl 3 is going to be used). .Pp The .Fn devstat_getnumdevs function returns the number of devices registered with the .Nm subsystem in the kernel. .Pp The .Fn devstat_getgeneration function returns the current generation of the .Nm list of devices in the kernel. .Pp The .Fn devstat_getversion function returns the current kernel .Nm version. .Pp The .Fn devstat_checkversion function checks the userland .Nm version against the kernel .Nm version. If the two are identical, it returns zero. Otherwise, it prints an appropriate error in .Va devstat_errbuf and returns \-1. .Pp The .Fn devstat_getdevs function fetches the current list of devices and statistics into the supplied .Vt statinfo structure. The .Vt statinfo structure can be found in .In devstat.h : .Bd -literal -offset indent struct statinfo { long cp_time[CPUSTATES]; long tk_nin; long tk_nout; struct devinfo *dinfo; long double snap_time; }; .Ed .Pp The .Fn devstat_getdevs function expects the .Vt statinfo structure to be allocated, and it also expects the .Va dinfo subelement to be allocated and zeroed prior to the first invocation of .Fn devstat_getdevs . The .Va dinfo subelement is used to store state between calls, and should not be modified after the first call to .Fn devstat_getdevs . The .Va dinfo subelement contains the following elements: .Bd -literal -offset indent struct devinfo { struct devstat *devices; u_int8_t *mem_ptr; long generation; int numdevs; }; .Ed .Pp The .Va kern.devstat.all .Xr sysctl 8 variable contains an array of .Nm structures, but at the head of the array is the current .Nm generation. The reason the generation is at the head of the buffer is so that userland software accessing the .Nm statistics information can atomically get both the statistics information and the corresponding generation number. If client software were forced to get the generation number via a separate .Xr sysctl 8 variable (which is available for convenience), the list of devices could change between the time the client gets the generation and the time the client gets the device list. .Pp The .Va mem_ptr subelement of the .Vt devinfo structure is a pointer to memory that is allocated, and resized if necessary, by .Fn devstat_getdevs . The devices subelement of the .Vt devinfo structure is basically a pointer to the beginning of the array of devstat structures from the .Va kern.devstat.all .Xr sysctl 8 variable (or the corresponding values read via .Xr kvm 3 ) . The generation subelement of the .Vt devinfo structure contains the corresponding generation number. The .Va numdevs subelement of the .Vt devinfo structure contains the current number of devices registered with the kernel .Nm subsystem. .Pp The .Fn devstat_selectdevs function selects devices to display based upon a number of criteria: .Bl -tag -width indent .It specified devices Specified devices are the first selection priority. These are generally devices specified by name by the user e.g.\& .Li da0 , da1 , cd0 . .It match patterns These are pattern matching expressions generated by .Fn devstat_buildmatch from user input. .It performance If performance mode is enabled, devices will be sorted based on the .Va bytes field in the .Vt device_selection structure passed in to .Fn devstat_selectdevs . The .Va bytes value currently must be maintained by the user. In the future, this may be done for him in a .Nm library routine. If no devices have been selected by name or by pattern, the performance tracking code will select every device in the system, and sort them by performance. If devices have been selected by name or pattern, the performance tracking code will honor those selections and will only sort among the selected devices. .It order in the devstat list If the selection mode is set to .Dv DS_SELECT_ADD , and if there are still less than .Fa maxshowdevs devices selected, .Fn devstat_selectdevs will automatically select up to .Fa maxshowdevs devices. .El .Pp The .Fn devstat_selectdevs function performs selections in four different modes: .Bl -tag -width ".Dv DS_SELECT_ADDONLY" .It Dv DS_SELECT_ADD In .Dq add mode, .Fn devstat_selectdevs will select any unselected devices specified by name or matching pattern. It will also select more devices, in devstat list order, until the number of selected devices is equal to .Fa maxshowdevs or until all devices are selected. .It Dv DS_SELECT_ONLY In .Dq only mode, .Fn devstat_selectdevs will clear all current selections, and will only select devices specified by name or by matching pattern. .It Dv DS_SELECT_REMOVE In .Dq remove mode, .Fn devstat_selectdevs will remove devices specified by name or by matching pattern. It will not select any additional devices. .It Dv DS_SELECT_ADDONLY In .Dq "add only" mode, .Fn devstat_selectdevs will select any unselected devices specified by name or matching pattern. In this respect it is identical to .Dq add mode. It will not, however, select any devices other than those specified. .El .Pp In all selection modes, .Fn devstat_selectdevs will not select any more than .Fa maxshowdevs devices. One exception to this is when you are in .Dq top mode and no devices have been selected. In this case, .Fn devstat_selectdevs will select every device in the system. Client programs must pay attention to selection order when deciding whether to pay attention to a particular device. This may be the wrong behavior, and probably requires additional thought. .Pp The .Fn devstat_selectdevs function handles allocation and resizing of the .Fa dev_select structure passed in by the client. The .Fn devstat_selectdevs function uses the .Fa numdevs and .Fa current_generation fields to track the current .Nm generation and number of devices. If .Fa num_selections is not the same as .Fa numdevs or if .Fa select_generation is not the same as .Fa current_generation , .Fn devstat_selectdevs will resize the selection list as necessary, and re-initialize the selection array. .Pp The .Fn devstat_buildmatch function takes a comma separated match string and compiles it into a .Vt devstat_match structure that is understood by .Fn devstat_selectdevs . Match strings have the following format: .Pp .D1 Ar device , Ns Ar type , Ns Ar if .Pp The .Fn devstat_buildmatch function takes care of allocating and reallocating the match list as necessary. Currently known match types include: .Bl -tag -width indent .It device type: .Bl -tag -width ".Li enclosure" -compact .It Li da Direct Access devices .It Li sa Sequential Access devices .It Li printer Printers .It Li proc Processor devices .It Li worm Write Once Read Multiple devices .It Li cd CD devices .It Li scanner Scanner devices .It Li optical Optical Memory devices .It Li changer Medium Changer devices .It Li comm Communication devices .It Li array Storage Array devices .It Li enclosure Enclosure Services devices .It Li floppy Floppy devices .El .It interface: .Bl -tag -width ".Li enclosure" -compact .It Li IDE Integrated Drive Electronics devices .It Li SCSI Small Computer System Interface devices .It Li other Any other device interface .El .It passthrough: .Bl -tag -width ".Li enclosure" -compact .It Li pass Passthrough devices .El .El .Pp The .Fn devstat_compute_statistics function provides complete statistics calculation. There are four arguments for which values .Em must be supplied: .Fa current , .Fa previous , .Fa etime , and the terminating argument for the varargs list, .Dv DSM_NONE . For most applications, the user will want to supply valid .Vt devstat structures for both .Fa current and .Fa previous . In some instances, for instance when calculating statistics since system boot, the user may pass in a .Dv NULL pointer for the .Fa previous argument. In that case, .Fn devstat_compute_statistics will use the total stats in the .Fa current structure to calculate statistics over .Fa etime . For each statistics to be calculated, the user should supply the proper enumerated type (listed below), and a variable of the indicated type. All statistics are either integer values, for which a .Vt u_int64_t is used, or floating point, for which a .Vt "long double" is used. The statistics that may be calculated are: .Bl -tag -width ".Dv DSM_TRANSFERS_PER_SECOND_OTHER" .It Dv DSM_NONE type: N/A .Pp This .Em must be the last argument passed to .Fn devstat_compute_statistics . It is an argument list terminator. .It Dv DSM_TOTAL_BYTES type: .Vt "u_int64_t *" .Pp The total number of bytes transferred between the acquisition of .Fa previous and .Fa current . .It Dv DSM_TOTAL_BYTES_READ .It Dv DSM_TOTAL_BYTES_WRITE .It Dv DSM_TOTAL_BYTES_FREE type: .Vt "u_int64_t *" .Pp The total number of bytes in transactions of the specified type between the acquisition of .Fa previous and .Fa current . .It Dv DSM_TOTAL_TRANSFERS type: .Vt "u_int64_t *" .Pp The total number of transfers between the acquisition of .Fa previous and .Fa current . .It Dv DSM_TOTAL_TRANSFERS_OTHER .It Dv DSM_TOTAL_TRANSFERS_READ .It Dv DSM_TOTAL_TRANSFERS_WRITE .It Dv DSM_TOTAL_TRANSFERS_FREE type: .Vt "u_int64_t *" .Pp The total number of transactions of the specified type between the acquisition of .Fa previous and .Fa current . .It Dv DSM_TOTAL_BLOCKS type: .Vt "u_int64_t *" .Pp The total number of blocks transferred between the acquisition of .Fa previous and .Fa current . This number is in terms of the blocksize reported by the device. If no blocksize has been reported (i.e., the block size is 0), a default blocksize of 512 bytes will be used in the calculation. .It Dv DSM_TOTAL_BLOCKS_READ .It Dv DSM_TOTAL_BLOCKS_WRITE .It Dv DSM_TOTAL_BLOCKS_FREE type: .Vt "u_int64_t *" .Pp The total number of blocks of the specified type between the acquisition of .Fa previous and .Fa current . This number is in terms of the blocksize reported by the device. If no blocksize has been reported (i.e., the block size is 0), a default blocksize of 512 bytes will be used in the calculation. .It Dv DSM_KB_PER_TRANSFER type: .Vt "long double *" .Pp The average number of kilobytes per transfer between the acquisition of .Fa previous and .Fa current . .It Dv DSM_KB_PER_TRANSFER_READ .It Dv DSM_KB_PER_TRANSFER_WRITE .It Dv DSM_KB_PER_TRANSFER_FREE type: .Vt "long double *" .Pp The average number of kilobytes in the specified type transaction between the acquisition of .Fa previous and .Fa current . .It Dv DSM_TRANSFERS_PER_SECOND type: .Vt "long double *" .Pp The average number of transfers per second between the acquisition of .Fa previous and .Fa current . .It Dv DSM_TRANSFERS_PER_SECOND_OTHER .It Dv DSM_TRANSFERS_PER_SECOND_READ .It Dv DSM_TRANSFERS_PER_SECOND_WRITE .It Dv DSM_TRANSFERS_PER_SECOND_FREE type: .Vt "long double *" .Pp The average number of transactions of the specified type per second between the acquisition of .Fa previous and .Fa current . .It Dv DSM_MB_PER_SECOND type: .Vt "long double *" .Pp The average number of megabytes transferred per second between the acquisition of .Fa previous and .Fa current . .It Dv DSM_MB_PER_SECOND_READ .It Dv DSM_MB_PER_SECOND_WRITE .It Dv DSM_MB_PER_SECOND_FREE type: .Vt "long double *" .Pp The average number of megabytes per second in the specified type of transaction between the acquisition of .Fa previous and .Fa current . .It Dv DSM_BLOCKS_PER_SECOND type: .Vt "long double *" .Pp The average number of blocks transferred per second between the acquisition of .Fa previous and .Fa current . This number is in terms of the blocksize reported by the device. If no blocksize has been reported (i.e., the block size is 0), a default blocksize of 512 bytes will be used in the calculation. .It Dv DSM_BLOCKS_PER_SECOND_READ .It Dv DSM_BLOCKS_PER_SECOND_WRITE .It Dv DSM_BLOCKS_PER_SECOND_FREE type: .Vt "long double *" .Pp The average number of blocks per second in the specified type of transaction between the acquisition of .Fa previous and .Fa current . This number is in terms of the blocksize reported by the device. If no blocksize has been reported (i.e., the block size is 0), a default blocksize of 512 bytes will be used in the calculation. .It Dv DSM_MS_PER_TRANSACTION type: .Vt "long double *" .Pp The average duration of transactions between the acquisition of .Fa previous and .Fa current . .It Dv DSM_MS_PER_TRANSACTION_OTHER .It Dv DSM_MS_PER_TRANSACTION_READ .It Dv DSM_MS_PER_TRANSACTION_WRITE .It Dv DSM_MS_PER_TRANSACTION_FREE type: .Vt "long double *" .Pp The average duration of transactions of the specified type between the acquisition of .Fa previous and .Fa current . .It Dv DSM_BUSY_PCT type: .Vt "long double *" .Pp The percentage of time the device had one or more transactions outstanding between the acquisition of .Fa previous and .Fa current . .It Dv DSM_QUEUE_LENGTH type: .Vt "u_int64_t *" .Pp The number of not yet completed transactions at the time when .Fa current was acquired. .It Dv DSM_SKIP type: N/A .Pp If you do not need a result from .Fn devstat_compute_statistics , just put .Dv DSM_SKIP as first (type) parameter and .Dv NULL as second parameter. This can be useful in scenarios where the statistics to be calculated are determined at run time. .El .Pp The .Fn devstat_compute_etime function provides an easy way to find the difference in seconds between two .Vt bintime structures. This is most commonly used in conjunction with the time recorded by the .Fn devstat_getdevs function (in .Vt "struct statinfo" ) each time it fetches the current .Nm list. .Sh RETURN VALUES The .Fn devstat_getnumdevs , .Fn devstat_getgeneration , and .Fn devstat_getversion function return the indicated sysctl variable, or \-1 if there is an error fetching the variable. .Pp The .Fn devstat_checkversion function returns 0 if the kernel and userland .Nm versions match. If they do not match, it returns \-1. .Pp The .Fn devstat_getdevs and .Fn devstat_selectdevs functions return \-1 in case of an error, 0 if there is no error, and 1 if the device list or selected devices have changed. A return value of 1 from .Fn devstat_getdevs is usually a hint to re-run .Fn devstat_selectdevs because the device list has changed. .Pp The .Fn devstat_buildmatch function returns \-1 for error, and 0 if there is no error. .Pp The .Fn devstat_compute_etime function returns the computed elapsed time. .Pp The .Fn devstat_compute_statistics function returns \-1 for error, and 0 for success. .Pp If an error is returned from one of the .Nm library functions, the reason for the error is generally printed in the global string .Va devstat_errbuf which is .Dv DEVSTAT_ERRBUF_SIZE characters long. .Sh SEE ALSO .Xr systat 1 , .Xr kvm 3 , .Xr sysctl 3 , .Xr iostat 8 , .Xr rpc.rstatd 8 , .Xr sysctl 8 , .Xr vmstat 8 , .Xr devstat 9 .Sh HISTORY The .Nm statistics system first appeared in .Fx 3.0 . The new interface (the functions prefixed with .Li devstat_ ) first appeared in .Fx 5.0 . .Sh AUTHORS .An Kenneth Merry Aq ken@FreeBSD.org .Sh BUGS There should probably be an interface to de-allocate memory allocated by .Fn devstat_getdevs , .Fn devstat_selectdevs , and .Fn devstat_buildmatch . .Pp The .Fn devstat_selectdevs function should probably not select more than .Fa maxshowdevs devices in .Dq top mode when no devices have been selected previously. .Pp There should probably be functions to perform the statistics buffer swapping that goes on in most of the clients of this library. .Pp The .Vt statinfo and .Vt devinfo structures should probably be cleaned up and thought out a little more. freebsd-libs-9.2+ds2/lib/libdevstat/Makefile0000644000000000000000000000163711317614257015664 0ustar # $FreeBSD$ LIB= devstat SHLIBDIR?= /lib # Bump DEVSTAT_USER_API_VER in devstat.h every time this is incremented. SHLIB_MAJOR= 7 SRCS= devstat.c INCS= devstat.h DPADD= ${LIBKVM} LDADD= -lkvm MAN= devstat.3 MLINKS+=devstat.3 devstat_getnumdevs.3 MLINKS+=devstat.3 devstat_getgeneration.3 MLINKS+=devstat.3 devstat_getversion.3 MLINKS+=devstat.3 devstat_checkversion.3 MLINKS+=devstat.3 devstat_getdevs.3 MLINKS+=devstat.3 devstat_selectdevs.3 MLINKS+=devstat.3 devstat_buildmatch.3 MLINKS+=devstat.3 devstat_compute_statistics.3 MLINKS+=devstat.3 devstat_compute_etime.3 MLINKS+=devstat.3 getnumdevs.3 MLINKS+=devstat.3 getgeneration.3 MLINKS+=devstat.3 getversion.3 MLINKS+=devstat.3 checkversion.3 MLINKS+=devstat.3 getdevs.3 MLINKS+=devstat.3 selectdevs.3 MLINKS+=devstat.3 buildmatch.3 MLINKS+=devstat.3 compute_stats.3 MLINKS+=devstat.3 compute_etime.3 CFLAGS+=-I${.CURDIR} WARNS?= 3 .include freebsd-libs-9.2+ds2/lib/libdevstat/devstat.h0000644000000000000000000001201610750376560016042 0ustar /* * Copyright (c) 1997, 1998 Kenneth D. Merry. * 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. 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 _DEVSTAT_H #define _DEVSTAT_H #include #include #include #include /* * Bumped every time we change the userland API. Hopefully this doesn't * happen very often! This should be bumped every time we have to * increment SHLIB_MAJOR in the libdevstat Makefile (for non-backwards * compatible API changes) and should also be bumped every time we make * backwards-compatible API changes, so application writers have a way to * determine when a particular feature is available. */ #define DEVSTAT_USER_API_VER 6 #define DEVSTAT_ERRBUF_SIZE 2048 /* size of the devstat library error string */ extern char devstat_errbuf[]; typedef enum { DEVSTAT_MATCH_NONE = 0x00, DEVSTAT_MATCH_TYPE = 0x01, DEVSTAT_MATCH_IF = 0x02, DEVSTAT_MATCH_PASS = 0x04 } devstat_match_flags; typedef enum { DSM_NONE, DSM_TOTAL_BYTES, DSM_TOTAL_BYTES_READ, DSM_TOTAL_BYTES_WRITE, DSM_TOTAL_TRANSFERS, DSM_TOTAL_TRANSFERS_READ, DSM_TOTAL_TRANSFERS_WRITE, DSM_TOTAL_TRANSFERS_OTHER, DSM_TOTAL_BLOCKS, DSM_TOTAL_BLOCKS_READ, DSM_TOTAL_BLOCKS_WRITE, DSM_KB_PER_TRANSFER, DSM_KB_PER_TRANSFER_READ, DSM_KB_PER_TRANSFER_WRITE, DSM_TRANSFERS_PER_SECOND, DSM_TRANSFERS_PER_SECOND_READ, DSM_TRANSFERS_PER_SECOND_WRITE, DSM_TRANSFERS_PER_SECOND_OTHER, DSM_MB_PER_SECOND, DSM_MB_PER_SECOND_READ, DSM_MB_PER_SECOND_WRITE, DSM_BLOCKS_PER_SECOND, DSM_BLOCKS_PER_SECOND_READ, DSM_BLOCKS_PER_SECOND_WRITE, DSM_MS_PER_TRANSACTION, DSM_MS_PER_TRANSACTION_READ, DSM_MS_PER_TRANSACTION_WRITE, DSM_SKIP, DSM_TOTAL_BYTES_FREE, DSM_TOTAL_TRANSFERS_FREE, DSM_TOTAL_BLOCKS_FREE, DSM_KB_PER_TRANSFER_FREE, DSM_MB_PER_SECOND_FREE, DSM_TRANSFERS_PER_SECOND_FREE, DSM_BLOCKS_PER_SECOND_FREE, DSM_MS_PER_TRANSACTION_OTHER, DSM_MS_PER_TRANSACTION_FREE, DSM_BUSY_PCT, DSM_QUEUE_LENGTH, DSM_MAX } devstat_metric; struct devstat_match { devstat_match_flags match_fields; devstat_type_flags device_type; int num_match_categories; }; struct devstat_match_table { const char * match_str; devstat_type_flags type; devstat_match_flags match_field; }; struct device_selection { u_int32_t device_number; char device_name[DEVSTAT_NAME_LEN]; int unit_number; int selected; u_int64_t bytes; int position; }; struct devinfo { struct devstat *devices; u_int8_t *mem_ptr; long generation; int numdevs; }; struct statinfo { long cp_time[CPUSTATES]; long tk_nin; long tk_nout; struct devinfo *dinfo; long double snap_time; }; typedef enum { DS_SELECT_ADD, DS_SELECT_ONLY, DS_SELECT_REMOVE, DS_SELECT_ADDONLY } devstat_select_mode; __BEGIN_DECLS int devstat_getnumdevs(kvm_t *kd); long devstat_getgeneration(kvm_t *kd); int devstat_getversion(kvm_t *kd); int devstat_checkversion(kvm_t *kd); int devstat_getdevs(kvm_t *kd, struct statinfo *stats); int devstat_selectdevs(struct device_selection **dev_select, int *num_selected, int *num_selections, long *select_generation, long current_generation, struct devstat *devices, int numdevs, struct devstat_match *matches, int num_matches, char **dev_selections, int num_dev_selections, devstat_select_mode select_mode, int maxshowdevs, int perf_select); int devstat_buildmatch(char *match_str, struct devstat_match **matches, int *num_matches); int devstat_compute_statistics(struct devstat *current, struct devstat *previous, long double etime, ...); long double devstat_compute_etime(struct bintime *cur_time, struct bintime *prev_time); __END_DECLS #endif /* _DEVSTAT_H */ freebsd-libs-9.2+ds2/lib/libsbuf/0000755000000000000000000000000012244372504013476 5ustar freebsd-libs-9.2+ds2/lib/libsbuf/Version.def0000644000000000000000000000006312142011516015570 0ustar # $FreeBSD$ FBSD_1.2 { }; FBSD_1.3 { } FBSD_1.2; freebsd-libs-9.2+ds2/lib/libsbuf/Makefile0000644000000000000000000000032211564531166015140 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-9.2+ds2/lib/libsbuf/Symbol.map0000644000000000000000000000050012142011516015423 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-9.2+ds2/lib/libipx/0000755000000000000000000000000012244372445013343 5ustar freebsd-libs-9.2+ds2/lib/libipx/Makefile0000644000000000000000000000023111317614257014777 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-9.2+ds2/lib/libipx/ipx_ntoa.c0000644000000000000000000000565610550564616015345 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-9.2+ds2/lib/libipx/ipx.30000644000000000000000000000746411436235001014226 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-9.2+ds2/lib/libipx/ipx_addr.c0000644000000000000000000001311610550564616015304 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-9.2+ds2/lib/libjail/0000755000000000000000000000000012244372471013461 5ustar freebsd-libs-9.2+ds2/lib/libjail/jail.h0000644000000000000000000000464611232615531014554 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-9.2+ds2/lib/libjail/jail_getid.c0000644000000000000000000000621511417657675015741 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-9.2+ds2/lib/libjail/jail.30000644000000000000000000001551511453610425014466 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-9.2+ds2/lib/libjail/jail.c0000644000000000000000000006534311757174256014570 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; njp++) { value = va_arg(ap, char *); if (jailparam_init(jp + njp, name) < 0 || jailparam_import(jp + njp, value) < 0) { jailparam_free(jp, njp); va_end(ap); return (-1); } } va_end(ap); jid = jailparam_set(jp, njp, flags); jailparam_free(jp, njp); return (jid); } /* * 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; 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; jp = realloc(jp, nlist * sizeof(*jp)); if (jp == NULL) { jailparam_free(jp, njp); return (-1); } } 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); 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-9.2+ds2/lib/libjail/Makefile0000644000000000000000000000105211317614257015120 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-9.2+ds2/lib/libalias/0000755000000000000000000000000012244372541013631 5ustar freebsd-libs-9.2+ds2/lib/libalias/Makefile0000644000000000000000000000010010506467343015264 0ustar # $FreeBSD$ SUBDIR= libalias modules .include freebsd-libs-9.2+ds2/lib/libalias/Makefile.inc0000644000000000000000000000005011343256170016032 0ustar # $FreeBSD$ .include "../Makefile.inc" freebsd-libs-9.2+ds2/lib/libalias/libalias/0000755000000000000000000000000012244372541015411 5ustar freebsd-libs-9.2+ds2/lib/libalias/libalias/Makefile0000644000000000000000000000035011343256170017045 0ustar # $FreeBSD$ .PATH: ${.CURDIR}/../../../sys/netinet/libalias LIB= alias SHLIBDIR?= /lib SHLIB_MAJOR= 7 MAN= libalias.3 SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_mod.c INCS= alias.h NO_WERROR= .include freebsd-libs-9.2+ds2/lib/libalias/modules/0000755000000000000000000000000012244372541015301 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/ftp/0000755000000000000000000000000012244372541016072 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/ftp/Makefile0000644000000000000000000000010010512202330017501 0ustar # $FreeBSD$ NAME= ftp SRCS= alias_ftp.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/Makefile0000644000000000000000000000020310506467343016740 0ustar # $FreeBSD$ .include "${.CURDIR}/../../../sys/modules/libalias/modules/modules.inc" SUBDIR= ${MODULES} .include freebsd-libs-9.2+ds2/lib/libalias/modules/skinny/0000755000000000000000000000000012244372541016614 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/skinny/Makefile0000644000000000000000000000010610512202330020231 0ustar # $FreeBSD$ NAME= skinny SRCS= alias_skinny.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/smedia/0000755000000000000000000000000012244372541016543 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/smedia/Makefile0000644000000000000000000000010610512202330020160 0ustar # $FreeBSD$ NAME= smedia SRCS= alias_smedia.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/nbt/0000755000000000000000000000000012244372541016064 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/nbt/Makefile0000644000000000000000000000010010512202330017473 0ustar # $FreeBSD$ NAME= nbt SRCS= alias_nbt.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/cuseeme/0000755000000000000000000000000012244372541016727 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/cuseeme/Makefile0000644000000000000000000000011010512202330020337 0ustar # $FreeBSD$ NAME= cuseeme SRCS= alias_cuseeme.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/irc/0000755000000000000000000000000012244372541016056 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/irc/Makefile0000644000000000000000000000010010512202330017465 0ustar # $FreeBSD$ NAME= irc SRCS= alias_irc.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/Makefile.inc0000644000000000000000000000022110512202330017464 0ustar # $FreeBSD$ .PATH: ${.CURDIR}/../../../../sys/netinet/libalias SHLIBDIR?= /lib LIB?= alias_${NAME} SHLIB_NAME?=libalias_${NAME}.so WARNS?= 1 freebsd-libs-9.2+ds2/lib/libalias/modules/pptp/0000755000000000000000000000000012244372541016264 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/pptp/Makefile0000644000000000000000000000010210512202330017675 0ustar # $FreeBSD$ NAME= pptp SRCS= alias_pptp.c .include freebsd-libs-9.2+ds2/lib/libalias/modules/dummy/0000755000000000000000000000000012244372541016434 5ustar freebsd-libs-9.2+ds2/lib/libalias/modules/dummy/Makefile0000644000000000000000000000010410512202330020047 0ustar # $FreeBSD$ NAME= dummy SRCS= alias_dummy.c .include freebsd-libs-9.2+ds2/lib/libmemstat/0000755000000000000000000000000012244372501014206 5ustar freebsd-libs-9.2+ds2/lib/libmemstat/memstat_all.c0000644000000000000000000000365510275140373016667 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-9.2+ds2/lib/libmemstat/memstat.c0000644000000000000000000002136211615472507016040 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-9.2+ds2/lib/libmemstat/memstat_malloc.c0000644000000000000000000002504511615472507017371 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-9.2+ds2/lib/libmemstat/Makefile0000644000000000000000000000141511230653404015645 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-9.2+ds2/lib/libmemstat/memstat_internal.h0000644000000000000000000001146011615472507017737 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-9.2+ds2/lib/libmemstat/memstat_uma.c0000644000000000000000000003104312044004310016653 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_full_bucket); 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-9.2+ds2/lib/libmemstat/libmemstat.30000644000000000000000000004207211746326015016445 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-9.2+ds2/lib/libmemstat/memstat.h0000644000000000000000000001562611615472507016053 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-9.2+ds2/lib/libutil/0000755000000000000000000000000012244372536013521 5ustar freebsd-libs-9.2+ds2/lib/libutil/trimdomain.30000644000000000000000000000524111361411226015737 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 7, 1999 .Dt TRIMDOMAIN 3 .Os .Sh NAME .Nm trimdomain .Nd "trim the current domain name from a host name" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft void .Fn trimdomain "char *fullhost" "int hostsize" .Sh DESCRIPTION The function .Fn trimdomain removes the current domain name from the passed .Ar fullhost name by writing a .Dv NUL character over the first period of the passed name. The current domain name is determined by calling .Xr gethostname 3 and removing everything up to the first period. The name is determined the first time this function is called and is cached for future use. .Pp The .Fn trimdomain function will only trim the domain name if the passed .Ar fullname ends with the current domain name and if the length of the resulting host name does not exceed .Ar hostsize . .Pp If the passed .Ar fullname is actually a .Dv DISPLAY specification of the form .Sm off .Ar host . domain : nn Oo . .Ar nn .Oc .Sm on and the domain name is the same as the local domain name, .Fn trimdomain will remove the embedded domain name, copying the screen and display numbers to the end of the base host name and resulting in .Sm off .Ar host : nn Op . Ar nn . .Sm on .Sh RETURN VALUES The .Fn trimdomain function does not return a value. .Sh SEE ALSO .Xr gethostname 3 freebsd-libs-9.2+ds2/lib/libutil/_secure_path.30000644000000000000000000000473011361411226016237 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-9.2+ds2/lib/libutil/trimdomain.c0000644000000000000000000000653710320654654016040 0ustar /*- * Copyright (c) 2001 Brian Somers * Based on original work by Atsushi Murai * 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 static int isDISP(const char *); /*- * Trim the current domain name from fullhost, but only if the result * is less than or equal to hostsize in length. * * This function understands $DISPLAY type fullhosts. * * For example: * * trimdomain("abcde.my.domain", 5) -> "abcde" * trimdomain("abcde.my.domain", 4) -> "abcde.my.domain" * trimdomain("abcde.my.domain:0.0", 9) -> "abcde:0.0" * trimdomain("abcde.my.domain:0.0", 8) -> "abcde.my.domain:0.0" */ void trimdomain(char *fullhost, int hostsize) { static size_t dlen; static int first = 1; static char domain[MAXHOSTNAMELEN]; char *end, *s; size_t len; if (first) { /* XXX: Should we assume that our domain is this persistent ? */ first = 0; if (gethostname(domain, sizeof(domain) - 1) == 0 && (s = strchr(domain, '.')) != NULL) memmove(domain, s + 1, strlen(s + 1) + 1); else domain[0] = '\0'; dlen = strlen(domain); } if (domain[0] == '\0') return; s = fullhost; end = s + hostsize + 1; if ((s = memchr(s, '.', (size_t)(end - s))) != NULL) { if (strncasecmp(s + 1, domain, dlen) == 0) { if (s[dlen + 1] == '\0') { /* Found -- lose the domain. */ *s = '\0'; } else if (s[dlen + 1] == ':' && isDISP(s + dlen + 2) && (len = strlen(s + dlen + 1)) < (size_t)(end - s)) { /* Found -- shuffle the DISPLAY back. */ memmove(s, s + dlen + 1, len + 1); } } } } /* * Is the given string NN or NN.NN where ``NN'' is an all-numeric string ? */ static int isDISP(const char *disp) { size_t w; int res; w = strspn(disp, "0123456789"); res = 0; if (w > 0) { if (disp[w] == '\0') res = 1; /* NN */ else if (disp[w] == '.') { disp += w + 1; w = strspn(disp, "0123456789"); if (w > 0 && disp[w] == '\0') res = 1; /* NN.NN */ } } return (res); } freebsd-libs-9.2+ds2/lib/libutil/libutil.h0000644000000000000000000001734611762426630015350 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); 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); int gr_tmp(int _mdf); struct group *gr_scan(const char *line); #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-9.2+ds2/lib/libutil/_secure_path.c0000644000000000000000000000452110161021420016303 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-9.2+ds2/lib/libutil/flopen.30000644000000000000000000000536311212534647015074 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-9.2+ds2/lib/libutil/kinfo_getallproc.c0000644000000000000000000000515311562731133017205 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-9.2+ds2/lib/libutil/uucplock.c0000644000000000000000000001271110550564616015514 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 = creat(lcktmpname, 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)) < 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)) < 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-9.2+ds2/lib/libutil/login_cap.h0000644000000000000000000001437611534427503015634 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-9.2+ds2/lib/libutil/login_crypt.c0000644000000000000000000000357107454274530016226 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-9.2+ds2/lib/libutil/uucplock.30000644000000000000000000001154211361411226015422 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-9.2+ds2/lib/libutil/flopen.c0000644000000000000000000000544311212534647015153 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-9.2+ds2/lib/libutil/kinfo_getallproc.30000644000000000000000000000461511562731133017127 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 July 9, 2009 .Os .Dt KINFO_GETALLPROC 3 .Sh NAME .Nm kinfo_getallproc .Nd function for getting process information of all processes from kernel .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In sys/types.h .In libutil.h .Ft struct kinfo_proc * .Fn kinfo_getallproc "int *cntp" .Sh DESCRIPTION This function is used for obtaining process information of all processes from the kernel. .Pp The .Ar cntp field is a pointer containing the number of process structures returned. This function is a wrapper around .Xr sysctl 3 with the .Dv KERN_PROC_PROC 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_getallproc function returns a pointer to .Ar cntp .Vt struct kinfo_proc structures 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_getallproc function returns .Dv NULL . .Sh SEE ALSO .Xr free 3 , .Xr malloc 3 , .Xr sysctl 3 freebsd-libs-9.2+ds2/lib/libutil/kinfo_getfile.c0000644000000000000000000000255711125406627016477 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-9.2+ds2/lib/libutil/login_tty.c0000644000000000000000000000413411324647143015674 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-9.2+ds2/lib/libutil/realhostname_sa.30000644000000000000000000001110011453610460016733 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-9.2+ds2/lib/libutil/login_auth.30000644000000000000000000000433111361411226015724 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-9.2+ds2/lib/libutil/kld.c0000644000000000000000000000471611434207220014432 0ustar /*- * Copyright (c) 2006 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. * * $FreeBSD$ */ #include #include #include #include #include #include int kld_isloaded(const char *name) { struct kld_file_stat fstat; struct module_stat mstat; const char *ko; int fid, mid; for (fid = kldnext(0); fid > 0; fid = kldnext(fid)) { fstat.version = sizeof(fstat); if (kldstat(fid, &fstat) != 0) continue; /* check if the file name matches the supplied name */ if (strcmp(fstat.name, name) == 0) return (1); /* strip .ko and try again */ if ((ko = strstr(fstat.name, ".ko")) != NULL && strlen(name) == (size_t)(ko - fstat.name) && strncmp(fstat.name, name, ko - fstat.name) == 0) return (1); /* look for a matching module within the file */ for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) { mstat.version = sizeof(mstat); if (modstat(mid, &mstat) != 0) continue; if (strcmp(mstat.name, name) == 0) return (1); } } return (0); } int kld_load(const char *name) { if (kldload(name) == -1 && errno != EEXIST) return (-1); return (0); } freebsd-libs-9.2+ds2/lib/libutil/login_times.30000644000000000000000000001225411361411226016107 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-9.2+ds2/lib/libutil/login_auth.c0000644000000000000000000000577507672666235016047 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)) < 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-9.2+ds2/lib/libutil/stub.c0000644000000000000000000000326607744210040014637 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-9.2+ds2/lib/libutil/login_times.c0000644000000000000000000000733411077135536016205 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, &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-9.2+ds2/lib/libutil/kld.30000644000000000000000000000527711361411226014357 0ustar .\"- .\" Copyright (c) 2006 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 February 18, 2006 .Dt KLD 3 .Os .Sh NAME .Nm kld_isloaded , .Nm kld_load .Nd kld utility functions .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In libutil.h .Ft int .Fn kld_isloaded "const char *name" .Ft int .Fn kld_load "const char *name" .Sh DESCRIPTION These functions facilitate loading kernel modules from userland applications. .Pp The .Fn kld_isloaded function takes a name and returns a non-zero value if a module of that name is currently loaded. The name can be either the name of a module file .Pq Pa cpufreq.ko , the same name without the .Pa .ko extension .Pq Pa cpufreq , or the name of a module contained within that file .Pq Pa cpu/ichss . Only the latter will return correct results if the module is compiled into the kernel. .Pp The .Fn kld_load function is a simple wrapper around the .Xr kldload 2 function. It returns zero if and only if the corresponding .Fn kldload call succeeded or returned .Er EEXIST (signifying that the requested module was already loaded). .Sh SEE ALSO .Xr kldfirstmod 2 , .Xr kldload 2 , .Xr kldnext 2 , .Xr kldstat 2 , .Xr modfnext 2 , .Xr modstat 2 , .Xr kld 4 .Sh HISTORY The .Fn kld_isloaded and .Fn kld_load functions first appeared in .Fx 6.3 . .Sh AUTHORS The .Fn kld_isloaded and .Fn kld_load functions and this manual page were written by .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org . freebsd-libs-9.2+ds2/lib/libutil/login_tty.30000644000000000000000000000430311361411226015602 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-9.2+ds2/lib/libutil/kinfo_getfile.30000644000000000000000000000502011426052171016376 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 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_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-9.2+ds2/lib/libutil/property.c0000644000000000000000000001345510342630230015542 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-9.2+ds2/lib/libutil/hexdump.30000644000000000000000000000571011361411226015247 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-9.2+ds2/lib/libutil/kinfo_getproc.30000644000000000000000000000455512117143733016441 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 .Os .Dt KINFO_GETPROC 3 .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-9.2+ds2/lib/libutil/property.30000644000000000000000000000566012000525767015474 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 sys/types.h .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-9.2+ds2/lib/libutil/hexdump.c0000644000000000000000000000567611032530041015332 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-9.2+ds2/lib/libutil/kinfo_getproc.c0000644000000000000000000000407311562731133016514 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-9.2+ds2/lib/libutil/login_cap.30000644000000000000000000003731611767532253015555 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-9.2+ds2/lib/libutil/Makefile0000644000000000000000000000505012000525767015155 0ustar # @(#)Makefile 8.1 (Berkeley) 6/4/93 # $FreeBSD$ SHLIBDIR?= /lib .include LIB= util SHLIB_MAJOR= 9 SRCS= _secure_path.c expand_number.c flopen.c fparseln.c gr_util.c \ hexdump.c humanize_number.c kinfo_getfile.c kinfo_getfile.c \ kinfo_getallproc.c kinfo_getproc.c kinfo_getvmmap.c kld.c \ login_auth.c login_cap.c \ login_class.c login_crypt.c login_ok.c login_times.c login_tty.c \ pidfile.c property.c pty.c pw_util.c quotafile.c realhostname.c \ stub.c trimdomain.c uucplock.c INCS= libutil.h login_cap.h CFLAGS+= -DLIBC_SCCS .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 .endif CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../libc/gen/ MAN+= kld.3 login_auth.3 login_tty.3 pty.3 \ login_cap.3 login_class.3 login_times.3 login_ok.3 \ _secure_path.3 uucplock.3 property.3 realhostname.3 \ realhostname_sa.3 trimdomain.3 fparseln.3 humanize_number.3 \ pidfile.3 flopen.3 expand_number.3 hexdump.3 \ kinfo_getfile.3 kinfo_getallproc.3 kinfo_getproc.3 \ kinfo_getvmmap.3 quotafile.3 MAN+= login.conf.5 MLINKS+= kld.3 kld_isloaded.3 kld.3 kld_load.3 MLINKS+= property.3 properties_read.3 property.3 properties_free.3 MLINKS+= property.3 property_find.3 MLINKS+= pty.3 openpty.3 pty.3 forkpty.3 MLINKS+=login_cap.3 login_getclassbyname.3 login_cap.3 login_close.3 \ login_cap.3 login_getclass.3 login_cap.3 login_getuserclass.3 \ login_cap.3 login_getcapstr.3 login_cap.3 login_getcaplist.3 \ login_cap.3 login_getstyle.3 login_cap.3 login_getcaptime.3 \ login_cap.3 login_getcapnum.3 login_cap.3 login_getcapsize.3 \ login_cap.3 login_getcapbool.3 login_cap.3 login_getpath.3 \ login_cap.3 login_getpwclass.3 login_cap.3 login_setcryptfmt.3 MLINKS+=login_class.3 setusercontext.3 login_class.3 setclasscontext.3 \ login_class.3 setclassenvironment.3 login_class.3 setclassresources.3 MLINKS+=login_times.3 parse_lt.3 login_times.3 in_ltm.3 \ login_times.3 in_lt.3 login_times.3 in_ltms.3 \ login_times.3 in_lts.3 MLINKS+=login_ok.3 auth_ttyok.3 login_ok.3 auth_hostok.3 \ login_ok.3 auth_timeok.3 MLINKS+=login_auth.3 auth_checknologin.3 login_auth.3 auth_cat.3 MLINKS+=uucplock.3 uu_lock.3 uucplock.3 uu_lock_txfr.3 \ uucplock.3 uu_unlock.3 uucplock.3 uu_lockerr.3 MLINKS+=pidfile.3 pidfile_open.3 \ pidfile.3 pidfile_write.3 \ pidfile.3 pidfile_close.3 \ pidfile.3 pidfile_remove.3 MLINKS+=quotafile.3 quota_open.3 \ quotafile.3 quota_fsname.3 \ quotafile.3 quota_qfname.3 \ quotafile.3 quota_statfs.3 \ quotafile.3 quota_read.3 \ quotafile.3 quota_write_limits.3 \ quotafile.3 quota_write_usage.3 \ quotafile.3 quota_close.3 .include freebsd-libs-9.2+ds2/lib/libutil/realhostname.c0000644000000000000000000001304611112657655016354 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-9.2+ds2/lib/libutil/login_ok.c0000644000000000000000000001340610362564233015466 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. * * Support allow/deny lists in login class capabilities */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include /* -- support functions -- */ /* * login_strinlist() * This function is intentionally public - reused by TAS. * Returns TRUE (non-zero) if a string matches a pattern * in a given array of patterns. 'flags' is passed directly * to fnmatch(3). */ int login_strinlist(const char **list, char const *str, int flags) { int rc = 0; if (str != NULL && *str != '\0') { int i = 0; while (rc == 0 && list[i] != NULL) rc = fnmatch(list[i++], str, flags) == 0; } return rc; } /* * login_str2inlist() * Locate either or two strings in a given list */ int login_str2inlist(const char **ttlst, const char *str1, const char *str2, int flags) { int rc = 0; if (login_strinlist(ttlst, str1, flags)) rc = 1; else if (login_strinlist(ttlst, str2, flags)) rc = 1; return rc; } /* * login_timelist() * This function is intentionally public - reused by TAS. * Returns an allocated list of time periods given an array * of time periods in ascii form. */ login_time_t * login_timelist(login_cap_t *lc, char const *cap, int *ltno, login_time_t **ltptr) { int j = 0; struct login_time *lt = NULL; const char **tl; if ((tl = login_getcaplist(lc, cap, NULL)) != NULL) { while (tl[j++] != NULL) ; if (*ltno >= j) lt = *ltptr; else if ((lt = realloc(*ltptr, j * sizeof(struct login_time))) != NULL) { *ltno = j; *ltptr = lt; } if (lt != NULL) { int i = 0; for (--j; i < j; i++) lt[i] = parse_lt(tl[i]); lt[i].lt_dow = LTM_NONE; } } return lt; } /* * login_ttyok() * This function is a variation of auth_ttyok(), but it checks two * arbitrary capability lists not necessarily related to access. * This hook is provided for the accounted/exclude accounting lists. */ int login_ttyok(login_cap_t *lc, const char *tty, const char *allowcap, const char *denycap) { int rc = 1; if (lc != NULL && tty != NULL && *tty != '\0') { struct ttyent *te; char *grp; const char **ttl; te = getttynam(tty); /* Need group name */ grp = te ? te->ty_group : NULL; ttl = login_getcaplist(lc, allowcap, NULL); if (ttl != NULL && !login_str2inlist(ttl, tty, grp, 0)) rc = 0; /* tty or ttygroup not in allow list */ else { ttl = login_getcaplist(lc, denycap, NULL); if (ttl != NULL && login_str2inlist(ttl, tty, grp, 0)) rc = 0; /* tty or ttygroup in deny list */ } } return rc; } /* * auth_ttyok() * Determine whether or not login on a tty is accessible for * a login class */ int auth_ttyok(login_cap_t *lc, const char * tty) { return login_ttyok(lc, tty, "ttys.allow", "ttys.deny"); } /* * login_hostok() * This function is a variation of auth_hostok(), but it checks two * arbitrary capability lists not necessarily related to access. * This hook is provided for the accounted/exclude accounting lists. */ int login_hostok(login_cap_t *lc, const char *host, const char *ip, const char *allowcap, const char *denycap) { int rc = 1; /* Default is ok */ if (lc != NULL && ((host != NULL && *host != '\0') || (ip != NULL && *ip != '\0'))) { const char **hl; hl = login_getcaplist(lc, allowcap, NULL); if (hl != NULL && !login_str2inlist(hl, host, ip, FNM_CASEFOLD)) rc = 0; /* host or IP not in allow list */ else { hl = login_getcaplist(lc, denycap, NULL); if (hl != NULL && login_str2inlist(hl, host, ip, FNM_CASEFOLD)) rc = 0; /* host or IP in deny list */ } } return rc; } /* * auth_hostok() * Determine whether or not login from a host is ok */ int auth_hostok(login_cap_t *lc, const char *host, const char *ip) { return login_hostok(lc, host, ip, "host.allow", "host.deny"); } /* * auth_timeok() * Determine whether or not login is ok at a given time */ int auth_timeok(login_cap_t *lc, time_t t) { int rc = 1; /* Default is ok */ if (lc != NULL && t != (time_t)0 && t != (time_t)-1) { struct tm *tptr; static int ltimesno = 0; static struct login_time *ltimes = NULL; if ((tptr = localtime(&t)) != NULL) { struct login_time *lt; lt = login_timelist(lc, "times.allow", <imesno, <imes); if (lt != NULL && in_ltms(lt, tptr, NULL) == -1) rc = 0; /* not in allowed times list */ else { lt = login_timelist(lc, "times.deny", <imesno, <imes); if (lt != NULL && in_ltms(lt, tptr, NULL) != -1) rc = 0; /* in deny times list */ } if (ltimes) { free(ltimes); ltimes = NULL; ltimesno = 0; } } } return rc; } freebsd-libs-9.2+ds2/lib/libutil/pty.c0000644000000000000000000000603311104051472014466 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-9.2+ds2/lib/libutil/auth.c0000644000000000000000000000315412000525767014625 0ustar /* * Simple authentication database 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 char * auth_getval(const char *name) { (void)name; return (NULL); } freebsd-libs-9.2+ds2/lib/libutil/login_ok.30000644000000000000000000001024311361411226015373 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-9.2+ds2/lib/libutil/pty.30000644000000000000000000000766311361411226014422 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-9.2+ds2/lib/libutil/login_cap.c0000644000000000000000000004632011104051401015600 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)) >= 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