--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/strptr.c Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,150 @@
+/*
+ * strptr.c - implementation of the elf_strptr(3) function.
+ * Copyright (C) 1995 - 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: strptr.c,v 1.11 2007/09/07 12:07:59 michael Exp $";
+#endif /* lint */
+
+char*
+elf_strptr(Elf *elf, size_t section, size_t offset) {
+ Elf_Data *data;
+ Elf_Scn *scn;
+ size_t n;
+ char *s;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!(scn = elf_getscn(elf, section))) {
+ return NULL;
+ }
+ if (scn->s_index == SHN_UNDEF) {
+ seterr(ERROR_NOSTRTAB);
+ return NULL;
+ }
+ /*
+ * checking the section header is more appropriate
+ */
+ if (elf->e_class == ELFCLASS32) {
+ if (scn->s_shdr32.sh_type != SHT_STRTAB) {
+ seterr(ERROR_NOSTRTAB);
+ return NULL;
+ }
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ if (scn->s_shdr64.sh_type != SHT_STRTAB) {
+ seterr(ERROR_NOSTRTAB);
+ return NULL;
+ }
+ }
+#endif /* __LIBELF64 */
+ else if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ return NULL;
+ }
+ /*
+ * Find matching buffer
+ */
+ n = 0;
+ data = NULL;
+ if (elf->e_elf_flags & ELF_F_LAYOUT) {
+ /*
+ * Programmer is responsible for d_off
+ * Note: buffers may be in any order!
+ */
+ while ((data = elf_getdata(scn, data))) {
+ n = data->d_off;
+ if (offset >= n && offset - n < data->d_size) {
+ /*
+ * Found it
+ */
+ break;
+ }
+ }
+ }
+ else {
+ /*
+ * Calculate offsets myself
+ */
+ while ((data = elf_getdata(scn, data))) {
+ if (data->d_align > 1) {
+ n += data->d_align - 1;
+ n -= n % data->d_align;
+ }
+ if (offset < n) {
+ /*
+ * Invalid offset: points into a hole
+ */
+ seterr(ERROR_BADSTROFF);
+ return NULL;
+ }
+ if (offset - n < data->d_size) {
+ /*
+ * Found it
+ */
+ break;
+ }
+ n += data->d_size;
+ }
+ }
+ if (data == NULL) {
+ /*
+ * Not found
+ */
+ seterr(ERROR_BADSTROFF);
+ return NULL;
+ }
+ if (data->d_buf == NULL) {
+ /*
+ * Buffer is NULL (usually the programmers' fault)
+ */
+ seterr(ERROR_NULLBUF);
+ return NULL;
+ }
+ offset -= n;
+ s = (char*)data->d_buf;
+ if (!(_elf_sanity_checks & SANITY_CHECK_STRPTR)) {
+ return s + offset;
+ }
+ /*
+ * Perform extra sanity check
+ */
+ for (n = offset; n < data->d_size; n++) {
+ if (s[n] == '\0') {
+ /*
+ * Return properly NUL terminated string
+ */
+ return s + offset;
+ }
+ }
+ /*
+ * String is not NUL terminated
+ * Return error to avoid SEGV in application
+ */
+ seterr(ERROR_UNTERM);
+ return NULL;
+}