mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 15:40:44 +00:00
ldconfig: support hints files of either byte-order
Make the ldconfig program accept hints files in little-endian and big-endian format on all architectures. The default format is the native byte-order of the respective host. This is expected to change when a version of the pkg command is available that implements support for either byte-order in its internal ldconfig function. (Already committed in the development tree of the pkg utility, a release is expected at the end of Q1/2024). This update adds the -B option to the ldconfig program. It enforces the creation of a big-endian hints file on a little-endian host. The main purpose to is support of tests with non-native byte-order files on little-endian hosts. It will be removed when all supported FreeBSD releases use little-endian hints files by default. When little-endian hints files are generally used, support of either byte-order in libexec/rtld can also be removed. When support for big-endian hints files is no longer required, the COND_SWAP macro in ldconfig and rtld shall be replaced by le32toh(), which just return their argument on little-endian architectures. Approved by: kib MFC after: 1 month Relnotes: yes Differential Revision: https://reviews.freebsd.org/D44093
This commit is contained in:
parent
cf4d9bf8b3
commit
e0dfecadf5
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -48,11 +49,12 @@
|
|||
|
||||
static void add_dir(const char *, const char *, bool);
|
||||
static void read_dirs_from_file(const char *, const char *);
|
||||
static void read_elf_hints(const char *, bool);
|
||||
static void read_elf_hints(const char *, bool, bool);
|
||||
static void write_elf_hints(const char *);
|
||||
|
||||
static const char *dirs[MAXDIRS];
|
||||
static int ndirs;
|
||||
static bool is_be;
|
||||
bool insecure;
|
||||
|
||||
static void
|
||||
|
@ -95,7 +97,7 @@ list_elf_hints(const char *hintsfile)
|
|||
int i;
|
||||
int nlibs;
|
||||
|
||||
read_elf_hints(hintsfile, 1);
|
||||
read_elf_hints(hintsfile, true, false);
|
||||
printf("%s:\n", hintsfile);
|
||||
printf("\tsearch directories:");
|
||||
for (i = 0; i < ndirs; i++)
|
||||
|
@ -183,8 +185,11 @@ read_dirs_from_file(const char *hintsfile, const char *listfile)
|
|||
fclose(fp);
|
||||
}
|
||||
|
||||
/* Convert between native byte order and forced little resp. big endian. */
|
||||
#define COND_SWAP(n) (is_be ? be32toh(n) : le32toh(n))
|
||||
|
||||
static void
|
||||
read_elf_hints(const char *hintsfile, bool must_exist)
|
||||
read_elf_hints(const char *hintsfile, bool must_exist, bool force_be)
|
||||
{
|
||||
int fd;
|
||||
struct stat s;
|
||||
|
@ -193,6 +198,7 @@ read_elf_hints(const char *hintsfile, bool must_exist)
|
|||
char *strtab;
|
||||
char *dirlist;
|
||||
char *p;
|
||||
int hdr_version;
|
||||
|
||||
if ((fd = open(hintsfile, O_RDONLY)) == -1) {
|
||||
if (errno == ENOENT && !must_exist)
|
||||
|
@ -214,14 +220,18 @@ read_elf_hints(const char *hintsfile, bool must_exist)
|
|||
close(fd);
|
||||
|
||||
hdr = (struct elfhints_hdr *)mapbase;
|
||||
if (hdr->magic != ELFHINTS_MAGIC)
|
||||
is_be = be32toh(hdr->magic) == ELFHINTS_MAGIC;
|
||||
if (COND_SWAP(hdr->magic) != ELFHINTS_MAGIC)
|
||||
errx(1, "\"%s\": invalid file format", hintsfile);
|
||||
if (hdr->version != 1)
|
||||
if (force_be && !is_be)
|
||||
errx(1, "\"%s\": incompatible endianness requested", hintsfile);
|
||||
hdr_version = COND_SWAP(hdr->version);
|
||||
if (hdr_version != 1)
|
||||
errx(1, "\"%s\": unrecognized file version (%d)", hintsfile,
|
||||
hdr->version);
|
||||
hdr_version);
|
||||
|
||||
strtab = (char *)mapbase + hdr->strtab;
|
||||
dirlist = strtab + hdr->dirlist;
|
||||
strtab = (char *)mapbase + COND_SWAP(hdr->strtab);
|
||||
dirlist = strtab + COND_SWAP(hdr->dirlist);
|
||||
|
||||
if (*dirlist != '\0')
|
||||
while ((p = strsep(&dirlist, ":")) != NULL)
|
||||
|
@ -229,13 +239,19 @@ read_elf_hints(const char *hintsfile, bool must_exist)
|
|||
}
|
||||
|
||||
void
|
||||
update_elf_hints(const char *hintsfile, int argc, char **argv, bool merge)
|
||||
update_elf_hints(const char *hintsfile, int argc, char **argv, bool merge,
|
||||
bool force_be)
|
||||
{
|
||||
struct stat s;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Remove "be32toh(1) == 1" from this condition to create
|
||||
* little-endian hints files on all architectures by default.
|
||||
*/
|
||||
is_be = be32toh(1) == 1 || force_be;
|
||||
if (merge)
|
||||
read_elf_hints(hintsfile, false);
|
||||
read_elf_hints(hintsfile, false, force_be);
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (stat(argv[i], &s) == -1)
|
||||
warn("warning: %s", argv[i]);
|
||||
|
@ -265,9 +281,9 @@ write_elf_hints(const char *hintsfile)
|
|||
if ((fp = fdopen(fd, "wb")) == NULL)
|
||||
err(1, "fdopen(%s)", tempname);
|
||||
|
||||
hdr.magic = ELFHINTS_MAGIC;
|
||||
hdr.version = 1;
|
||||
hdr.strtab = sizeof hdr;
|
||||
hdr.magic = COND_SWAP(ELFHINTS_MAGIC);
|
||||
hdr.version = COND_SWAP(1);
|
||||
hdr.strtab = COND_SWAP(sizeof hdr);
|
||||
hdr.strsize = 0;
|
||||
hdr.dirlist = 0;
|
||||
memset(hdr.spare, 0, sizeof hdr.spare);
|
||||
|
@ -278,8 +294,10 @@ write_elf_hints(const char *hintsfile)
|
|||
for (i = 1; i < ndirs; i++)
|
||||
hdr.strsize += 1 + strlen(dirs[i]);
|
||||
}
|
||||
hdr.dirlistlen = hdr.strsize;
|
||||
hdr.dirlistlen = COND_SWAP(hdr.strsize);
|
||||
hdr.strsize++; /* For the null terminator */
|
||||
/* convert in-place from native to target endianness */
|
||||
hdr.strsize = COND_SWAP(hdr.strsize);
|
||||
|
||||
/* Write the header. */
|
||||
if (fwrite(&hdr, 1, sizeof hdr, fp) != sizeof hdr)
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd May 15, 2021
|
||||
.Dd February 28, 2024
|
||||
.Dt LDCONFIG 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -41,7 +41,7 @@
|
|||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 32
|
||||
.Op Fl Rimrv
|
||||
.Op Fl BRimrv
|
||||
.Op Fl f Ar hints_file
|
||||
.Op Ar directory | Ar
|
||||
.Sh DESCRIPTION
|
||||
|
@ -105,6 +105,11 @@ Generate the hints for 32-bit ABI shared libraries
|
|||
on 64-bit systems that support running 32-bit binaries.
|
||||
.It Fl elf
|
||||
Ignored for backwards compatibility.
|
||||
.It Fl B
|
||||
Force writing big-endian binary data´to the hints file.
|
||||
The default is to create little-endian hints files on all architectures.
|
||||
Reading of and merging into hints files preserves the endianness of the
|
||||
existing hints file.
|
||||
.It Fl R
|
||||
Appends pathnames on the command line to the directory list from
|
||||
the hints file.
|
||||
|
@ -159,7 +164,7 @@ invocations with
|
|||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ld 1 ,
|
||||
.Xr ld-elf.so.1 ,
|
||||
.Xr ld-elf.so.1 1 ,
|
||||
.Xr link 5
|
||||
.Sh HISTORY
|
||||
A
|
||||
|
|
|
@ -57,9 +57,9 @@ main(int argc, char **argv)
|
|||
{
|
||||
const char *hints_file;
|
||||
int c;
|
||||
bool is_32, justread, merge, rescan, verbose;
|
||||
bool is_32, justread, merge, rescan, force_be, verbose;
|
||||
|
||||
is_32 = justread = merge = rescan = verbose = false;
|
||||
force_be = is_32 = justread = merge = rescan = verbose = false;
|
||||
|
||||
while (argc > 1) {
|
||||
if (strcmp(argv[1], "-aout") == 0) {
|
||||
|
@ -80,8 +80,11 @@ main(int argc, char **argv)
|
|||
hints_file = __PATH_ELF_HINTS("32");
|
||||
else
|
||||
hints_file = _PATH_ELF_HINTS;
|
||||
while((c = getopt(argc, argv, "Rf:imrsv")) != -1) {
|
||||
while((c = getopt(argc, argv, "BRf:imrsv")) != -1) {
|
||||
switch (c) {
|
||||
case 'B':
|
||||
force_be = true;
|
||||
break;
|
||||
case 'R':
|
||||
rescan = true;
|
||||
break;
|
||||
|
@ -115,7 +118,7 @@ main(int argc, char **argv)
|
|||
if (argc == optind)
|
||||
rescan = true;
|
||||
update_elf_hints(hints_file, argc - optind,
|
||||
argv + optind, merge || rescan);
|
||||
argv + optind, merge || rescan, force_be);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
@ -124,7 +127,7 @@ static void
|
|||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: ldconfig [-32] [-elf] [-Rimrv] [-f hints_file] "
|
||||
"usage: ldconfig [-32] [-elf] [-BRimrv] [-f hints_file]"
|
||||
"[directory | file ...]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ extern bool insecure; /* -i flag, needed here for elfhints.c */
|
|||
|
||||
__BEGIN_DECLS
|
||||
void list_elf_hints(const char *);
|
||||
void update_elf_hints(const char *, int, char **, bool);
|
||||
void update_elf_hints(const char *, int, char **, bool, bool);
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue