Commit 1cfabf34 by Ian Lance Taylor Committed by Ian Lance Taylor

simple-object.h: New file.

include/:
	* simple-object.h: New file.
libiberty/:
	* simple-object.c: New file.
	* simple-object-common.h: New file.
	* simple-object-elf.c: New file.
	* simple-object-mach-o.c: New file.
	* simple-object-coff.c: New file.
	* simple-object.txh: New file.
	* configure.ac: Add AC_TYPE_SSIZE_T.
	* Makefile.in: Rebuild dependencies.
	(CFILES): Add simple-object.c, simple-object-coff,
	simple-object-elf.c, and simple-object-mach-o.c.
	(REQUIRED_OFILES): Add corresponding object files.
	* configure: Rebuild.
	* config.in: Rebuild.
	* functions.texi: Rebuild.

Co-Authored-By: Dave Korn <dave.korn.cygwin@gmail.com>
Co-Authored-By: Iain Sandoe <iains@gcc.gnu.org>

From-SVN: r166185
parent fee3eacd
2010-11-02 Ian Lance Taylor <iant@google.com>
* simple-object.h: New file.
2010-10-15 Dave Korn <dave.korn.cygwin@gmail.com>
Sync LD plugin patch series (part 1/6) with src/include/.
......
/* simple-object.h -- simple routines to read and write object files
Copyright 2010 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifndef SIMPLE_OBJECT_H
#define SIMPLE_OBJECT_H
#include <stddef.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* This header file provides four types with associated functions.
They are used to read and write object files. This is a minimal
interface, intended to support the needs of gcc without bringing in
all the power and complexity of BFD. */
/* The type simple_object_read * is used to read an existing object
file. */
typedef struct simple_object_read_struct simple_object_read;
/* Create an simple_object_read given DESCRIPTOR, an open file
descriptor, and OFFSET, an offset within the file. The offset is
for use with archives, and should be 0 for an ordinary object file.
The descriptor must remain open until done with the returned
simple_object_read. SEGMENT_NAME is used on Mach-O and is required
on that platform: it means to only look at sections within the
segment with that name. It is ignored for other object file
formats. On error, this function returns NULL, and sets *ERRMSG to
an error string and sets *ERR to an errno value or 0 if there is no
relevant errno. */
extern simple_object_read *
simple_object_start_read (int descriptor, off_t offset,
const char *segment_name, const char **errmsg,
int *err);
/* Call PFN for each section in SIMPLE_OBJECT, passing it the section
name, offset within the file of the section contents, and length of
the section contents. The offset within the file is relative to
the offset passed to simple_object_start_read. The DATA argument
to simple_object_find_sections is passed on to PFN. If PFN returns
0, the loop is stopped and simple_object_find_sections returns. If
PFN returns non-zero, the loop continues. On success this returns
NULL. On error it returns an error string, and sets *ERR to an
errno value or 0 if there is no relevant errno. */
extern const char *
simple_object_find_sections (simple_object_read *simple_object,
int (*pfn) (void *data, const char *,
off_t offset, off_t length),
void *data,
int *err);
/* Look for the section NAME in SIMPLE_OBJECT. This returns
information for the first section NAME in SIMPLE_OBJECT. Note that
calling this multiple times is inefficient; use
simple_object_find_sections instead.
If found, return 1 and set *OFFSET to the offset in the file of the
section contents and set *LENGTH to the length of the section
contents. *OFFSET will be relative to the offset passed to
simple_object_start_read.
If the section is not found, and no error occurs, return 0 and set
*ERRMSG to NULL.
If an error occurs, return 0, set *ERRMSG to an error message, and
set *ERR to an errno value or 0 if there is no relevant errno. */
extern int
simple_object_find_section (simple_object_read *simple_object,
const char *name, off_t *offset, off_t *length,
const char **errmsg, int *err);
/* Release all resources associated with SIMPLE_OBJECT. This does not
close the file descriptor. */
extern void
simple_object_release_read (simple_object_read *);
/* The type simple_object_attributes holds the attributes of an object
file that matter for creating a file or ensuring that two files are
compatible. This is a set of magic numbers. */
typedef struct simple_object_attributes_struct simple_object_attributes;
/* Fetch the attributes of SIMPLE_OBJECT. This information will
persist until simple_object_attributes_release is called, even if
SIMPLE_OBJECT is closed. On error this returns NULL, sets *ERRMSG
to an error message, and sets *ERR to an errno value or 0 if there
isn't one. */
extern simple_object_attributes *
simple_object_fetch_attributes (simple_object_read *simple_object,
const char **errmsg, int *err);
/* Compare ATTRS1 and ATTRS2. If they could be linked together
without error, return NULL. Otherwise, return an error message,
set *ERR to an errno value or 0 if there isn't one. */
extern const char *
simple_object_attributes_compare (simple_object_attributes *attrs1,
simple_object_attributes *attrs2,
int *err);
/* Release all resources associated with ATTRS. */
extern void
simple_object_release_attributes (simple_object_attributes *attrs);
/* The type simple_object_write is used to create a new object file. */
typedef struct simple_object_write_struct simple_object_write;
/* Start creating a new object file which is like ATTRS. You must
fetch attribute information from an existing object file before you
can create a new one. There is currently no support for creating
an object file de novo. The segment name is only used on Mach-O,
where it is required. It means that all sections are created
within that segment. It is ignored for other object file formats.
On error this function returns NULL, sets *ERRMSG to an error
message, and sets *ERR to an errno value or 0 if there isn't
one. */
extern simple_object_write *
simple_object_start_write (simple_object_attributes *attrs,
const char *segment_name,
const char **errmsg, int *err);
/* The type simple_object_write_section is a handle for a section
which is being written. */
typedef struct simple_object_write_section_struct simple_object_write_section;
/* Add a section to SIMPLE_OBJECT. NAME is the name of the new
section. ALIGN is the required alignment expressed as the number
of required low-order 0 bits (e.g., 2 for alignment to a 32-bit
boundary). The section is created as containing data, readable,
not writable, not executable, not loaded at runtime. On error this
returns NULL, sets *ERRMSG to an error message, and sets *ERR to an
errno value or 0 if there isn't one. */
extern simple_object_write_section *
simple_object_write_create_section (simple_object_write *simple_object,
const char *name, unsigned int align,
const char **errmsg, int *err);
/* Add data BUFFER/SIZE to SECTION in SIMPLE_OBJECT. If COPY is
non-zero, the data will be copied into memory if necessary. If
COPY is zero, BUFFER must persist until SIMPLE_OBJECT is released.
On success this returns NULL. On error this returns an error
message, and sets *ERR to an errno value or 0 if there isn't
one. */
extern const char *
simple_object_write_add_data (simple_object_write *simple_object,
simple_object_write_section *section,
const void *buffer, size_t size,
int copy, int *err);
/* Write the complete object file to DESCRIPTOR, an open file
descriptor. This returns NULL on success. On error this returns
an error message, and sets *ERR to an errno value or 0 if there
isn't one. */
extern const char *
simple_object_write_to_file (simple_object_write *simple_object,
int descriptor, int *err);
/* Release all resources associated with SIMPLE_OBJECT, including any
simple_object_write_section's that may have been created. */
extern void
simple_object_release_write (simple_object_write *);
#ifdef __cplusplus
}
#endif
#endif
2010-11-02 Ian Lance Taylor <iant@google.com>
Dave Korn <dave.korn.cygwin@gmail.com>
Iain Sandoe <iains@gcc.gnu.org>
* simple-object.c: New file.
* simple-object-common.h: New file.
* simple-object-elf.c: New file.
* simple-object-mach-o.c: New file.
* simple-object-coff.c: New file.
* simple-object.txh: New file.
* configure.ac: Add AC_TYPE_SSIZE_T.
* Makefile.in: Rebuild dependencies.
(CFILES): Add simple-object.c, simple-object-coff,
simple-object-elf.c, and simple-object-mach-o.c.
(REQUIRED_OFILES): Add corresponding object files.
* configure: Rebuild.
* config.in: Rebuild.
* functions.texi: Rebuild.
2010-10-29 Ian Lance Taylor <iant@google.com>
* setproctitle.c: Add space after function name in @deftypefn
......
......@@ -2,8 +2,8 @@
# Originally written by K. Richard Pixley <rich@cygnus.com>.
#
# Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
# 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
# Foundation
# 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
# Free Software Foundation
#
# This file is part of the libiberty library.
# Libiberty is free software; you can redistribute it and/or
......@@ -145,6 +145,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \
physmem.c putenv.c \
random.c regex.c rename.c rindex.c \
safe-ctype.c setenv.c setproctitle.c sha1.c sigsetmask.c \
simple-object.c simple-object-coff.c simple-object-elf.c \
simple-object-mach-o.c \
snprintf.c sort.c \
spaces.c splay-tree.c stpcpy.c stpncpy.c strcasecmp.c \
strchr.c strdup.c strerror.c strncasecmp.c strncmp.c \
......@@ -172,11 +174,15 @@ REQUIRED_OFILES = \
./getruntime.$(objext) ./hashtab.$(objext) ./hex.$(objext) \
./lbasename.$(objext) ./lrealpath.$(objext) \
./make-relative-prefix.$(objext) ./make-temp-file.$(objext) \
./objalloc.$(objext) ./obstack.$(objext) \
./objalloc.$(objext) \
./obstack.$(objext) \
./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \
./pex-common.$(objext) ./pex-one.$(objext) \
./@pexecute@.$(objext) \
./safe-ctype.$(objext) ./sort.$(objext) ./spaces.$(objext) \
./safe-ctype.$(objext) \
./simple-object.$(objext) ./simple-object-coff.$(objext) \
./simple-object-elf.$(objext) ./simple-object-mach-o.$(objext) \
./sort.$(objext) ./spaces.$(objext) \
./splay-tree.$(objext) ./strerror.$(objext) \
./strsignal.$(objext) ./unlink-if-ordinary.$(objext) \
./xatexit.$(objext) ./xexit.$(objext) ./xmalloc.$(objext) \
......@@ -312,7 +318,7 @@ TEXISRC = \
# Additional files that have texi snippets that need to be collected
# and sorted. Some are here because the sources are imported from
# elsewhere. Others represent headers in ../include.
TEXIFILES = fnmatch.txh pexecute.txh
TEXIFILES = fnmatch.txh pexecute.txh simple-object.txh
libiberty.info : $(srcdir)/libiberty.texi $(TEXISRC)
$(MAKEINFO) -I$(srcdir) $(srcdir)/libiberty.texi
......@@ -965,6 +971,38 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/sigsetmask.c $(OUTPUT_OPTION)
./simple-object-coff.$(objext): $(srcdir)/simple-object-coff.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(srcdir)/simple-object-common.h $(INCDIR)/simple-object.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/simple-object-coff.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/simple-object-coff.c $(OUTPUT_OPTION)
./simple-object-elf.$(objext): $(srcdir)/simple-object-elf.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(srcdir)/simple-object-common.h $(INCDIR)/simple-object.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/simple-object-elf.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/simple-object-elf.c $(OUTPUT_OPTION)
./simple-object-mach-o.$(objext): $(srcdir)/simple-object-mach-o.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(srcdir)/simple-object-common.h $(INCDIR)/simple-object.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/simple-object-mach-o.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/simple-object-mach-o.c $(OUTPUT_OPTION)
./simple-object.$(objext): $(srcdir)/simple-object.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(srcdir)/simple-object-common.h $(INCDIR)/simple-object.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/simple-object.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/simple-object.c $(OUTPUT_OPTION)
./snprintf.$(objext): $(srcdir)/snprintf.c $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/snprintf.c -o pic/$@; \
......
......@@ -467,6 +467,9 @@
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to the type of an unsigned integer type wide enough to hold a
pointer, if such a type exists, and if the system does not define it. */
#undef uintptr_t
......
......@@ -5203,6 +5203,17 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
if test "x$ac_cv_type_ssize_t" = x""yes; then :
else
cat >>confdefs.h <<_ACEOF
#define ssize_t int
_ACEOF
fi
# Given the above check, we always have uintptr_t or a fallback
# definition. So define HAVE_UINTPTR_T in case any imported code
......
......@@ -290,6 +290,7 @@ fi
AC_TYPE_INTPTR_T
AC_TYPE_UINTPTR_T
AC_TYPE_SSIZE_T
# Given the above check, we always have uintptr_t or a fallback
# definition. So define HAVE_UINTPTR_T in case any imported code
......
......@@ -1181,6 +1181,186 @@ be the value @code{1}).
@end deftypefn
@c simple-object.txh:87
@deftypefn Extension {const char *} simple_object_attributes_compare (simple_object_attributes *@var{attrs1}, simple_object_attributes *@var{attrs2}, int *@var{err})
Compare @var{attrs1} and @var{attrs2}. If they could be linked
together without error, return @code{NULL}. Otherwise, return an
error message and set @code{*@var{err}} to an errno value or @code{0}
if there is no relevant errno.
@end deftypefn
@c simple-object.txh:73
@deftypefn Extension {simple_object_attributes *} simple_object_fetch_attributes (simple_object_read *@var{simple_object}, const char **@var{errmsg}, int *@var{err})
Fetch the attributes of @var{simple_object}. The attributes are
internal information such as the format of the object file, or the
architecture it was compiled for. This information will persist until
@code{simple_object_attributes_release} is called, even if
@var{simple_object} itself is released.
On error this returns @code{NULL}, sets @code{*@var{errmsg}} to an
error message, and sets @code{*@var{err}} to an errno value or
@code{0} if there is no relevant errno.
@end deftypefn
@c simple-object.txh:44
@deftypefn Extension {int} simple_object_find_section (simple_object_read *@var{simple_object} off_t *@var{offset}, off_t *@var{length}, const char **@var{errmsg}, int *@var{err})
Look for the section @var{name} in @var{simple_object}. This returns
information for the first section with that name.
If found, return 1 and set @code{*@var{offset}} to the offset in the
file of the section contents and set @code{*@var{length}} to the
length of the section contents. The value in @code{*@var{offset}}
will be relative to the offset passed to
@code{simple_object_open_read}.
If the section is not found, and no error occurs,
@code{simple_object_find_section} returns @code{0} and set
@code{*@var{errmsg}} to @code{NULL}.
If an error occurs, @code{simple_object_find_section} returns
@code{0}, sets @code{*@var{errmsg}} to an error message, and sets
@code{*@var{err}} to an errno value or @code{0} if there is no
relevant errno.
@end deftypefn
@c simple-object.txh:25
@deftypefn Extension {const char *} simple_object_find_sections (simple_object_read *@var{simple_object}, int (*@var{pfn}) (void *@var{data}, const char *@var{name}, off_t @var{offset}, off_t @var{length}), void *@var{data}, int *@var{err})
This function calls @var{pfn} for each section in @var{simple_object}.
It calls @var{pfn} with the section name, the offset within the file
of the section contents, and the length of the section contents. The
offset within the file is relative to the offset passed to
@code{simple_object_open_read}. The @var{data} argument to this
function is passed along to @var{pfn}.
If @var{pfn} returns @code{0}, the loop over the sections stops and
@code{simple_object_find_sections} returns. If @var{pfn} returns some
other value, the loop continues.
On success @code{simple_object_find_sections} returns. On error it
returns an error string, and sets @code{*@var{err}} to an errno value
or @code{0} if there is no relevant errno.
@end deftypefn
@c simple-object.txh:2
@deftypefn Extension {simple_object_read *} simple_object_open_read (int @var{descriptor}, off_t @var{offset}, const char *{segment_name}, const char **@var{errmsg}, int *@var{err})
Opens an object file for reading. Creates and returns an
@code{simple_object_read} pointer which may be passed to other
functions to extract data from the object file.
@var{descriptor} holds a file descriptor which permits reading.
@var{offset} is the offset into the file; this will be @code{0} in the
normal case, but may be a different value when reading an object file
in an archive file.
@var{segment_name} is only used with the Mach-O file format used on
Darwin aka Mac OS X. It is required on that platform, and means to
only look at sections within the segment with that name. The
parameter is ignored on other systems.
If an error occurs, this functions returns @code{NULL} and sets
@code{*@var{errmsg}} to an error string and sets @code{*@var{err}} to
an errno value or @code{0} if there is no relevant errno.
@end deftypefn
@c simple-object.txh:96
@deftypefn Extension {void} simple_object_release_attributes (simple_object_attributes *@var{attrs})
Release all resources associated with @var{attrs}.
@end deftypefn
@c simple-object.txh:66
@deftypefn Extension {void} simple_object_release_read (simple_object_read *@var{simple_object})
Release all resources associated with @var{simple_object}. This does
not close the file descriptor.
@end deftypefn
@c simple-object.txh:164
@deftypefn Extension {void} simple_object_release_write (simple_object_write *@var{simple_object})
Release all resources associated with @var{simple_object}.
@end deftypefn
@c simple-object.txh:102
@deftypefn Extension {simple_object_write *} simple_object_start_write (simple_object_attributes @var{attrs}, const char *@var{segment_name}, const char **@var{errmsg}, int *@var{err})
Start creating a new object file using the object file format
described in @var{attrs}. You must fetch attribute information from
an existing object file before you can create a new one. There is
currently no support for creating an object file de novo.
@var{segment_name} is only used with Mach-O as found on Darwin aka Mac
OS X. The parameter is required on that target. It means that all
sections are created within the named segment. It is ignored for
other object file formats.
On error @code{simple_object_start_write} returns @code{NULL}, sets
@code{*@var{ERRMSG}} to an error message, and sets @code{*@var{err}}
to an errno value or @code{0} if there is no relevant errno.
@end deftypefn
@c simple-object.txh:137
@deftypefn Extension {const char *} simple_object_write_add_data (simple_object_write *@var{simple_object}, simple_object_write_section *@var{section}, const void *@var{buffer}, size_t @var{size}, int @var{copy}, int *@var{err})
Add data @var{buffer}/@var{size} to @var{section} in
@var{simple_object}. If @var{copy} is non-zero, the data will be
copied into memory if necessary. If @var{copy} is zero, @var{buffer}
must persist until @code{simple_object_write_to_file} is called. is
released.
On success this returns @code{NULL}. On error this returns an error
message, and sets @code{*@var{err}} to an errno value or 0 if there is
no relevant erro.
@end deftypefn
@c simple-object.txh:120
@deftypefn Extension {simple_object_write_section *} simple_object_write_create_section (simple_object_write *@var{simple_object}, const char *@var{name}, unsigned int @var{align}, const char **@var{errmsg}, int *@var{err})
Add a section to @var{simple_object}. @var{name} is the name of the
new section. @var{align} is the required alignment expressed as the
number of required low-order 0 bits (e.g., 2 for alignment to a 32-bit
boundary).
The section is created as containing data, readable, not writable, not
executable, not loaded at runtime. The section is not written to the
file until @code{simple_object_write_to_file} is called.
On error this returns @code{NULL}, sets @code{*@var{errmsg}} to an
error message, and sets @code{*@var{err}} to an errno value or
@code{0} if there is no relevant errno.
@end deftypefn
@c simple-object.txh:151
@deftypefn Extension {const char *} simple_object_write_to_file (simple_object_write *@var{simple_object}, int @var{descriptor}, int *@var{err})
Write the complete object file to @var{descriptor}, an open file
descriptor. This writes out all the data accumulated by calls to
@code{simple_object_write_create_section} and
@var{simple_object_write_add_data}.
This returns @code{NULL} on success. On error this returns an error
message and sets @code{*@var{err}} to an errno value or @code{0} if
there is no relevant errno.
@end deftypefn
@c snprintf.c:28
@deftypefn Supplemental int snprintf (char *@var{buf}, size_t @var{n}, const char *@var{format}, ...)
......
/* simple-object.c -- simple routines to read and write object files.
Copyright 2010 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
#include "config.h"
#include "libiberty.h"
#include "simple-object.h"
#include <errno.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#include "simple-object-common.h"
/* The known object file formats. */
static const struct simple_object_functions * const format_functions[] =
{
&simple_object_elf_functions,
&simple_object_mach_o_functions,
&simple_object_coff_functions
};
/* Read data from a file using the simple_object error reporting
conventions. */
int
simple_object_internal_read (int descriptor, off_t offset,
unsigned char *buffer, size_t size,
const char **errmsg, int *err)
{
ssize_t got;
if (lseek (descriptor, offset, SEEK_SET) < 0)
{
*errmsg = "lseek";
*err = errno;
return 0;
}
got = read (descriptor, buffer, size);
if (got < 0)
{
*errmsg = "read";
*err = errno;
return 0;
}
if ((size_t) got < size)
{
*errmsg = "file too short";
*err = 0;
return 0;
}
return 1;
}
/* Write data to a file using the simple_object error reporting
conventions. */
int
simple_object_internal_write (int descriptor, off_t offset,
const unsigned char *buffer, size_t size,
const char **errmsg, int *err)
{
ssize_t wrote;
if (lseek (descriptor, offset, SEEK_SET) < 0)
{
*errmsg = "lseek";
*err = errno;
return 0;
}
wrote = write (descriptor, buffer, size);
if (wrote < 0)
{
*errmsg = "write";
*err = errno;
return 0;
}
if ((size_t) wrote < size)
{
*errmsg = "short write";
*err = 0;
return 0;
}
return 1;
}
/* Open for read. */
simple_object_read *
simple_object_start_read (int descriptor, off_t offset,
const char *segment_name, const char **errmsg,
int *err)
{
unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
size_t len, i;
if (!simple_object_internal_read (descriptor, offset, header,
SIMPLE_OBJECT_MATCH_HEADER_LEN,
errmsg, err))
return NULL;
len = sizeof (format_functions) / sizeof (format_functions[0]);
for (i = 0; i < len; ++i)
{
void *data;
data = format_functions[i]->match (header, descriptor, offset,
segment_name, errmsg, err);
if (data != NULL)
{
simple_object_read *ret;
ret = XNEW (simple_object_read);
ret->descriptor = descriptor;
ret->offset = offset;
ret->functions = format_functions[i];
ret->data = data;
return ret;
}
}
*errmsg = "file not recognized";
*err = 0;
return NULL;
}
/* Find all sections. */
const char *
simple_object_find_sections (simple_object_read *sobj,
int (*pfn) (void *, const char *, off_t, off_t),
void *data,
int *err)
{
return sobj->functions->find_sections (sobj, pfn, data, err);
}
/* Internal data passed to find_one_section. */
struct find_one_section_data
{
/* The section we are looking for. */
const char *name;
/* Where to store the section offset. */
off_t *offset;
/* Where to store the section length. */
off_t *length;
/* Set if the name is found. */
int found;
};
/* Internal function passed to find_sections. */
static int
find_one_section (void *data, const char *name, off_t offset, off_t length)
{
struct find_one_section_data *fosd = (struct find_one_section_data *) data;
if (strcmp (name, fosd->name) != 0)
return 1;
*fosd->offset = offset;
*fosd->length = length;
fosd->found = 1;
/* Stop iteration. */
return 0;
}
/* Find a section. */
int
simple_object_find_section (simple_object_read *sobj, const char *name,
off_t *offset, off_t *length,
const char **errmsg, int *err)
{
struct find_one_section_data fosd;
fosd.name = name;
fosd.offset = offset;
fosd.length = length;
fosd.found = 0;
*errmsg = simple_object_find_sections (sobj, find_one_section,
(void *) &fosd, err);
if (*errmsg != NULL)
return 0;
if (!fosd.found)
return 0;
return 1;
}
/* Fetch attributes. */
simple_object_attributes *
simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
int *err)
{
void *data;
simple_object_attributes *ret;
data = sobj->functions->fetch_attributes (sobj, errmsg, err);
if (data == NULL)
return NULL;
ret = XNEW (simple_object_attributes);
ret->functions = sobj->functions;
ret->data = data;
return ret;
}
/* Release an simple_object_read. */
void
simple_object_release_read (simple_object_read *sobj)
{
sobj->functions->release_read (sobj->data);
XDELETE (sobj);
}
/* Compare attributes. */
const char *
simple_object_attributes_compare (simple_object_attributes *attrs1,
simple_object_attributes *attrs2,
int *err)
{
if (attrs1->functions != attrs2->functions)
{
*err = 0;
return "different object file format";
}
return attrs1->functions->attributes_compare (attrs1->data, attrs2->data,
err);
}
/* Release an attributes structure. */
void
simple_object_release_attributes (simple_object_attributes *attrs)
{
attrs->functions->release_attributes (attrs->data);
XDELETE (attrs);
}
/* Start creating an object file. */
simple_object_write *
simple_object_start_write (simple_object_attributes *attrs,
const char *segment_name, const char **errmsg,
int *err)
{
void *data;
simple_object_write *ret;
data = attrs->functions->start_write (attrs->data, errmsg, err);
if (data == NULL)
return NULL;
ret = XNEW (simple_object_write);
ret->functions = attrs->functions;
ret->segment_name = xstrdup (segment_name);
ret->sections = NULL;
ret->last_section = NULL;
ret->data = data;
return ret;
}
/* Start creating a section. */
simple_object_write_section *
simple_object_write_create_section (simple_object_write *sobj, const char *name,
unsigned int align,
const char **errmsg ATTRIBUTE_UNUSED,
int *err ATTRIBUTE_UNUSED)
{
simple_object_write_section *ret;
ret = XNEW (simple_object_write_section);
ret->next = NULL;
ret->name = xstrdup (name);
ret->align = align;
ret->buffers = NULL;
ret->last_buffer = NULL;
if (sobj->last_section == NULL)
{
sobj->sections = ret;
sobj->last_section = ret;
}
else
{
sobj->last_section->next = ret;
sobj->last_section = ret;
}
return ret;
}
/* Add data to a section. */
const char *
simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
simple_object_write_section *section,
const void *buffer,
size_t size, int copy,
int *err ATTRIBUTE_UNUSED)
{
struct simple_object_write_section_buffer *wsb;
wsb = XNEW (struct simple_object_write_section_buffer);
wsb->next = NULL;
wsb->size = size;
if (!copy)
{
wsb->buffer = buffer;
wsb->free_buffer = NULL;
}
else
{
wsb->free_buffer = (void *) XNEWVEC (char, size);
memcpy (wsb->free_buffer, buffer, size);
wsb->buffer = wsb->free_buffer;
}
if (section->last_buffer == NULL)
{
section->buffers = wsb;
section->last_buffer = wsb;
}
else
{
section->last_buffer->next = wsb;
section->last_buffer = wsb;
}
return NULL;
}
/* Write the complete object file. */
const char *
simple_object_write_to_file (simple_object_write *sobj, int descriptor,
int *err)
{
return sobj->functions->write_to_file (sobj, descriptor, err);
}
/* Release an simple_object_write. */
void
simple_object_release_write (simple_object_write *sobj)
{
simple_object_write_section *section;
free (sobj->segment_name);
section = sobj->sections;
while (section != NULL)
{
struct simple_object_write_section_buffer *buffer;
simple_object_write_section *next_section;
buffer = section->buffers;
while (buffer != NULL)
{
struct simple_object_write_section_buffer *next_buffer;
if (buffer->free_buffer != NULL)
XDELETEVEC (buffer->free_buffer);
next_buffer = buffer->next;
XDELETE (buffer);
buffer = next_buffer;
}
next_section = section->next;
free (section->name);
XDELETE (section);
section = next_section;
}
sobj->functions->release_write (sobj->data);
XDELETE (sobj);
}
@c -*- mode: texinfo -*-
@deftypefn Extension {simple_object_read *} simple_object_open_read (int @var{descriptor}, off_t @var{offset}, const char *{segment_name}, const char **@var{errmsg}, int *@var{err})
Opens an object file for reading. Creates and returns an
@code{simple_object_read} pointer which may be passed to other
functions to extract data from the object file.
@var{descriptor} holds a file descriptor which permits reading.
@var{offset} is the offset into the file; this will be @code{0} in the
normal case, but may be a different value when reading an object file
in an archive file.
@var{segment_name} is only used with the Mach-O file format used on
Darwin aka Mac OS X. It is required on that platform, and means to
only look at sections within the segment with that name. The
parameter is ignored on other systems.
If an error occurs, this functions returns @code{NULL} and sets
@code{*@var{errmsg}} to an error string and sets @code{*@var{err}} to
an errno value or @code{0} if there is no relevant errno.
@end deftypefn
@deftypefn Extension {const char *} simple_object_find_sections (simple_object_read *@var{simple_object}, int (*@var{pfn}) (void *@var{data}, const char *@var{name}, off_t @var{offset}, off_t @var{length}), void *@var{data}, int *@var{err})
This function calls @var{pfn} for each section in @var{simple_object}.
It calls @var{pfn} with the section name, the offset within the file
of the section contents, and the length of the section contents. The
offset within the file is relative to the offset passed to
@code{simple_object_open_read}. The @var{data} argument to this
function is passed along to @var{pfn}.
If @var{pfn} returns @code{0}, the loop over the sections stops and
@code{simple_object_find_sections} returns. If @var{pfn} returns some
other value, the loop continues.
On success @code{simple_object_find_sections} returns. On error it
returns an error string, and sets @code{*@var{err}} to an errno value
or @code{0} if there is no relevant errno.
@end deftypefn
@deftypefn Extension {int} simple_object_find_section (simple_object_read *@var{simple_object} off_t *@var{offset}, off_t *@var{length}, const char **@var{errmsg}, int *@var{err})
Look for the section @var{name} in @var{simple_object}. This returns
information for the first section with that name.
If found, return 1 and set @code{*@var{offset}} to the offset in the
file of the section contents and set @code{*@var{length}} to the
length of the section contents. The value in @code{*@var{offset}}
will be relative to the offset passed to
@code{simple_object_open_read}.
If the section is not found, and no error occurs,
@code{simple_object_find_section} returns @code{0} and set
@code{*@var{errmsg}} to @code{NULL}.
If an error occurs, @code{simple_object_find_section} returns
@code{0}, sets @code{*@var{errmsg}} to an error message, and sets
@code{*@var{err}} to an errno value or @code{0} if there is no
relevant errno.
@end deftypefn
@deftypefn Extension {void} simple_object_release_read (simple_object_read *@var{simple_object})
Release all resources associated with @var{simple_object}. This does
not close the file descriptor.
@end deftypefn
@deftypefn Extension {simple_object_attributes *} simple_object_fetch_attributes (simple_object_read *@var{simple_object}, const char **@var{errmsg}, int *@var{err})
Fetch the attributes of @var{simple_object}. The attributes are
internal information such as the format of the object file, or the
architecture it was compiled for. This information will persist until
@code{simple_object_attributes_release} is called, even if
@var{simple_object} itself is released.
On error this returns @code{NULL}, sets @code{*@var{errmsg}} to an
error message, and sets @code{*@var{err}} to an errno value or
@code{0} if there is no relevant errno.
@end deftypefn
@deftypefn Extension {const char *} simple_object_attributes_compare (simple_object_attributes *@var{attrs1}, simple_object_attributes *@var{attrs2}, int *@var{err})
Compare @var{attrs1} and @var{attrs2}. If they could be linked
together without error, return @code{NULL}. Otherwise, return an
error message and set @code{*@var{err}} to an errno value or @code{0}
if there is no relevant errno.
@end deftypefn
@deftypefn Extension {void} simple_object_release_attributes (simple_object_attributes *@var{attrs})
Release all resources associated with @var{attrs}.
@end deftypefn
@deftypefn Extension {simple_object_write *} simple_object_start_write (simple_object_attributes @var{attrs}, const char *@var{segment_name}, const char **@var{errmsg}, int *@var{err})
Start creating a new object file using the object file format
described in @var{attrs}. You must fetch attribute information from
an existing object file before you can create a new one. There is
currently no support for creating an object file de novo.
@var{segment_name} is only used with Mach-O as found on Darwin aka Mac
OS X. The parameter is required on that target. It means that all
sections are created within the named segment. It is ignored for
other object file formats.
On error @code{simple_object_start_write} returns @code{NULL}, sets
@code{*@var{ERRMSG}} to an error message, and sets @code{*@var{err}}
to an errno value or @code{0} if there is no relevant errno.
@end deftypefn
@deftypefn Extension {simple_object_write_section *} simple_object_write_create_section (simple_object_write *@var{simple_object}, const char *@var{name}, unsigned int @var{align}, const char **@var{errmsg}, int *@var{err})
Add a section to @var{simple_object}. @var{name} is the name of the
new section. @var{align} is the required alignment expressed as the
number of required low-order 0 bits (e.g., 2 for alignment to a 32-bit
boundary).
The section is created as containing data, readable, not writable, not
executable, not loaded at runtime. The section is not written to the
file until @code{simple_object_write_to_file} is called.
On error this returns @code{NULL}, sets @code{*@var{errmsg}} to an
error message, and sets @code{*@var{err}} to an errno value or
@code{0} if there is no relevant errno.
@end deftypefn
@deftypefn Extension {const char *} simple_object_write_add_data (simple_object_write *@var{simple_object}, simple_object_write_section *@var{section}, const void *@var{buffer}, size_t @var{size}, int @var{copy}, int *@var{err})
Add data @var{buffer}/@var{size} to @var{section} in
@var{simple_object}. If @var{copy} is non-zero, the data will be
copied into memory if necessary. If @var{copy} is zero, @var{buffer}
must persist until @code{simple_object_write_to_file} is called. is
released.
On success this returns @code{NULL}. On error this returns an error
message, and sets @code{*@var{err}} to an errno value or 0 if there is
no relevant erro.
@end deftypefn
@deftypefn Extension {const char *} simple_object_write_to_file (simple_object_write *@var{simple_object}, int @var{descriptor}, int *@var{err})
Write the complete object file to @var{descriptor}, an open file
descriptor. This writes out all the data accumulated by calls to
@code{simple_object_write_create_section} and
@var{simple_object_write_add_data}.
This returns @code{NULL} on success. On error this returns an error
message and sets @code{*@var{err}} to an errno value or @code{0} if
there is no relevant errno.
@end deftypefn
@deftypefn Extension {void} simple_object_release_write (simple_object_write *@var{simple_object})
Release all resources associated with @var{simple_object}.
@end deftypefn
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment