Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Add the beginnings of ARCH_INDEP package support.
Matthew Seaman committed 13 years ago
commit e089b1df7eac0099194c665655661b4633ee17d0
parent 22a4246
7 files changed +133 -51
modified libpkg/pkg.c
@@ -176,6 +176,15 @@ pkg_is_valid(struct pkg *pkg)
	return (EPKG_OK);
}

+
int
+
pkg_is_arch_indep(struct pkg *pkg)
+
{
+
	if (pkg->flags & PKG_CONTAINS_ARCH_DEP)
+
		return EPKG_FATAL;
+
	else
+
		return EPKG_OK;
+
}
+

static int
pkg_vget(struct pkg const *const pkg, va_list ap)
{
modified libpkg/pkg.h
@@ -257,6 +257,7 @@ typedef enum _pkg_config_key {
	PKG_CONFIG_AUTODEPS = 12,
	PKG_CONFIG_ABI = 13,
	PKG_CONFIG_DEVELOPER_MODE = 14,
+
	PKG_CONFIG_ARCH_INDEP = 15,
} pkg_config_key;

typedef enum {
@@ -327,6 +328,11 @@ void pkg_free(struct pkg *);
int pkg_is_valid(struct pkg *);

/**
+
 * Check if a package is marked architecture independent
+
 */
+
int pkg_is_arch_indep(struct pkg *);
+

+
/**
 * Open a package file archive and retrive informations.
 * @param p A pointer to pkg allocated by pkg_new(), or if it points to a
 * NULL pointer, the function allocate a new pkg using pkg_new().
@@ -436,6 +442,8 @@ int pkg_shlibs(struct pkg *pkg, struct pkg_shlib **shlib);
 * @return An error code
 */

+
#define PKG_CONTAINS_ARCH_DEP (1<<24) /* Don't conflict with PKG_LOAD_* q.v. */
+

int pkg_analyse_files(struct pkgdb *, struct pkg *);
/**
 * Generic setter for simple attributes.
@@ -930,6 +938,7 @@ void pkg_test_filesum(struct pkg *);
void pkg_recompute(struct pkgdb *, struct pkg *);

int pkg_get_myarch(char *pkgarch, size_t sz);
+
int pkg_get_myarch_indep(char *pkgarch, size_t sz);

void pkgdb_cmd(int argc, char **argv);
#endif
modified libpkg/pkg_config.c
@@ -151,6 +151,12 @@ static struct config_entry c[] = {
		"DEVELOPER_MODE",
		"NO",
		{ NULL }
+
	},
+
	[PKG_CONFIG_ARCH_INDEP] = {
+
		BOOL,
+
		"ARCH_INDEP",
+
		"NO",
+
		{ NULL }
	}
};

modified libpkg/pkg_elf.c
@@ -130,6 +130,14 @@ analyse_elf(struct pkgdb *db, struct pkg *pkg, const char *fpath)
	size_t dynidx;
	const char *osname;

+
	bool shlibs = false;
+
	bool autodeps = false;
+
	bool arch_indep = false;
+

+
	pkg_config_bool(PKG_CONFIG_AUTODEPS, &autodeps);
+
	pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);
+
	pkg_config_bool(PKG_CONFIG_ARCH_INDEP, &arch_indep);
+

	int fd;

	if ((fd = open(fpath, O_RDONLY, 0)) < 0) {
@@ -154,6 +162,14 @@ analyse_elf(struct pkgdb *db, struct pkg *pkg, const char *fpath)
		return (EPKG_END); /* Not an elf file: no results */
	}

+
	if (arch_indep)
+
		pkg->flags |= PKG_CONTAINS_ARCH_DEP;
+

+
	if (!autodeps && !shlibs) {
+
	   ret = EPKG_OK;
+
	   goto cleanup;
+
	}
+

	if (gelf_getehdr(e, &elfhdr) == NULL) {
		ret = EPKG_FATAL;
		pkg_emit_error("getehdr() failed: %s.", elf_errmsg(-1));
@@ -233,16 +249,21 @@ pkg_analyse_files(struct pkgdb *db, struct pkg *pkg)
	int ret = EPKG_OK;
	bool shlibs = false;
	bool autodeps = false;
+
	bool arch_indep = false;

	pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);
	pkg_config_bool(PKG_CONFIG_AUTODEPS, &autodeps);
+
	pkg_config_bool(PKG_CONFIG_ARCH_INDEP, &arch_indep);

-
	if (!autodeps && !shlibs)
+
	if (!autodeps && !shlibs && !arch_indep)
		return (EPKG_OK);

	if (elf_version(EV_CURRENT) == EV_NONE)
		return (EPKG_FATAL);

+
	if (arch_indep)
+
		pkg->flags &= ~PKG_CONTAINS_ARCH_DEP; /* Assume no architecture dependence, for contradiction */
+

	while (pkg_files(pkg, &file) == EPKG_OK)
		analyse_elf(db, pkg, pkg_file_get(file, PKG_FILE_PATH));

@@ -262,8 +283,8 @@ elf_corres_to_string(struct _elf_corres* m, int e)
}


-
int
-
pkg_get_myarch(char *dest, size_t sz)
+
static int
+
get_myarch(char *dest, size_t sz, bool arch_indep)
{
	Elf *elf = NULL;
	GElf_Ehdr elfhdr;
@@ -338,44 +359,51 @@ pkg_get_myarch(char *dest, size_t sz)
	for (i = 0; osname[i] != '\0'; i++)
		osname[i] = (char)tolower(osname[i]);

-
	snprintf(dest, sz, "%s:%d:%s:%s",
-
	    osname,
-
	    version / 100000,
-
	    elf_corres_to_string(mach_corres, (int) elfhdr.e_machine),
-
	    elf_corres_to_string(wordsize_corres, (int)elfhdr.e_ident[EI_CLASS]));
-

-
	switch (elfhdr.e_machine) {
-
		case EM_ARM:
-
			snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s:%s",
-
			    elf_corres_to_string(endian_corres, (int) elfhdr.e_ident[EI_DATA]),
-
			    (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ? "eabi" : "oabi",
-
			    (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ? "softfp" : "vfp");
-
			break;
-
		case EM_MIPS:
-
			/*
-
			 * this is taken from binutils sources:
-
			 * include/elf/mips.h
-
			 * mapping is figured out from binutils:
-
			 * gas/config/tc-mips.c
-
			 */
-
			switch (elfhdr.e_flags & EF_MIPS_ABI) {
-
				case E_MIPS_ABI_O32:
-
					abi = "o32";
-
					break;
-
				case E_MIPS_ABI_N32:
-
					abi = "n32";
-
					break;
-
				default:
-
					if (elfhdr.e_ident[EI_DATA] == ELFCLASS32)
+
	if (arch_indep) {
+
		snprintf(dest, sz, "%s:%d:%s",
+
			 osname,
+
			 version / 100000,
+
			 "arch-indep");
+
	} else {
+
		snprintf(dest, sz, "%s:%d:%s:%s",
+
			 osname,
+
			 version / 100000,
+
			 elf_corres_to_string(mach_corres, (int) elfhdr.e_machine),
+
			 elf_corres_to_string(wordsize_corres, (int)elfhdr.e_ident[EI_CLASS]));
+

+
		switch (elfhdr.e_machine) {
+
			case EM_ARM:
+
				snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s:%s",
+
					 elf_corres_to_string(endian_corres, (int) elfhdr.e_ident[EI_DATA]),
+
					 (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ? "eabi" : "oabi",
+
					 (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ? "softfp" : "vfp");
+
				break;
+
			case EM_MIPS:
+
				/*
+
				 * this is taken from binutils sources:
+
				 * include/elf/mips.h
+
				 * mapping is figured out from binutils:
+
				 * gas/config/tc-mips.c
+
				 */
+
				switch (elfhdr.e_flags & EF_MIPS_ABI) {
+
					case E_MIPS_ABI_O32:
						abi = "o32";
-
					else if (elfhdr.e_ident[EI_DATA] == ELFCLASS64)
-
						abi = "n64";
-
					break;
-
			}
-
			snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s",
-
			    elf_corres_to_string(endian_corres, (int) elfhdr.e_ident[EI_DATA]),
-
			    abi);
-
			break;
+
						break;
+
					case E_MIPS_ABI_N32:
+
						abi = "n32";
+
						break;
+
					default:
+
						if (elfhdr.e_ident[EI_DATA] == ELFCLASS32)
+
							abi = "o32";
+
						else if (elfhdr.e_ident[EI_DATA] == ELFCLASS64)
+
							abi = "n64";
+
						break;
+
				}
+
				snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s",
+
					 elf_corres_to_string(endian_corres, (int) elfhdr.e_ident[EI_DATA]),
+
					 abi);
+
				break;
+
		}
	}

cleanup:
@@ -385,3 +413,15 @@ cleanup:
	close(fd);
	return (ret);
}
+

+
int
+
pkg_get_myarch(char *dest, size_t sz)
+
{
+
	return (get_myarch(dest, sz, false));
+
}
+

+
int
+
pkg_get_myarch_indep(char *dest, size_t sz)
+
{
+
	return (get_myarch(dest, sz, true));
+
}
modified pkg/main.c
@@ -266,6 +266,8 @@ main(int argc, char **argv)
			printf("Custom keywords directory: %s\n", buf ? buf : "none");
			pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &b);
			printf("Developer mode: %s\n", b ? "yes" : "no");
+
			pkg_config_bool(PKG_CONFIG_ARCH_INDEP, &b);
+
			printf("Detect achitecture independence: %s\n", b ? "yes" : "no");
		}
		pkg_config_bool(PKG_CONFIG_MULTIREPOS, &b);
		if (b) {
modified pkg/pkg.conf.5
@@ -111,6 +111,11 @@ forgotten by the maintainer.
default: off
.It Cm ABI: string
the abi of the package you want to install, by default the /bin/sh abi is used
+
.It Cm ARCH_INDEP: boolean
+
Analyse package contents to detect when it consists entirely of
+
architecture independent files (ie. no ELF objects are contained
+
within it)
+
default: off
.El
.Sh ENVIRONMENT
An environment variable with the same name as the option in the configuration
modified pkg/register.c
@@ -93,6 +93,7 @@ exec_register(int argc, char **argv)
	size_t size;

	bool legacy = false;
+
	bool arch_indep = false;

	int i;
	int ret = EPKG_OK, retcode = EPKG_OK;
@@ -138,17 +139,7 @@ exec_register(int argc, char **argv)
	if (plist == NULL)
		errx(EX_USAGE, "missing -f flag");

-
	if (arch == NULL) {
-
		/*
-
		 * do not take the one from configuration on purpose
-
		 * but the real abi of the package
-
		 */
-
		pkg_get_myarch(myarch, BUFSIZ);
-
		pkg_set(pkg, PKG_ARCH, myarch);
-
	} else {
-
		pkg_set(pkg, PKG_ARCH, arch);
-
		free(arch);
-
	}
+
	pkg_config_bool(PKG_CONFIG_ARCH_INDEP, &arch_indep);

	if (mdir == NULL)
		errx(EX_USAGE, "missing -m flag");
@@ -208,6 +199,26 @@ exec_register(int argc, char **argv)

	pkg_analyse_files(db, pkg);

+
	if (arch == NULL) {
+
		/*
+
		 * do not take the one from configuration on purpose
+
		 * but the real abi of the package.
+
		 *
+
		 * Don't label any package as arch-indep unless arch_indep
+
		 * is set: default to treating everything as
+
		 * architecture dependent.
+
		 */
+
		if (arch_indep && pkg_is_arch_indep(pkg) == EPKG_OK)
+
			pkg_get_myarch_indep(myarch, BUFSIZ);
+
		else
+
			pkg_get_myarch(myarch, BUFSIZ);
+

+
		pkg_set(pkg, PKG_ARCH, myarch);
+
	} else {
+
		pkg_set(pkg, PKG_ARCH, arch);
+
		free(arch);
+
	}
+

	if (input_path != NULL) {
		pkg_copy_tree(pkg, input_path, "/");
		free(input_path);