Subject: Re: more on non-executable mappings vs. emulations
To: Christos Zoulas <>
From: Alistair Crooks <>
List: tech-kern
Date: 07/14/2004 15:46:20
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Jul 14, 2004 at 08:28:46AM -0400, Christos Zoulas wrote:
> On Jul 13, 11:12pm, (Chuck Silvers) wrote:
> -- Subject: Re: more on non-executable mappings vs. emulations
> | On Mon, Jul 12, 2004 at 12:59:18PM -0400, Christos Zoulas wrote:
> | > | the ppc ELF tool should be trivial, I'll write it this evening.
> | 
> | there's a source file attached that implements this.
> | I was thinking we could make a pkg for it and have the suse73_base pkg
> | have a BUILD_DEPENDS on it, then we can fix the broken ldconfig binary
> | as we install it.
> Wow, I did not think that it would be that simple. Let's see what the
> pkgsrc people think about it.

I've made a pkgsrc entry for it, attached to this mail.  Please let me
know if I've forgotten anything.
> Thanks for solving the problem(s)!

Indeed - a huge round of thanks from me for that, too.


Content-Type: application/x-shar
Content-Disposition: attachment; filename="fixelfprot.shar"
Content-Transfer-Encoding: quoted-printable

# This is a shell archive.  Save it in a file, remove anything before=0A# t=
his line, and then unpack it by entering "sh file".  Note, it may=0A# creat=
e directories; files and directories will be owned by you and=0A# have defa=
ult permissions.=0A#=0A# This archive contains:=0A#=0A#	fixelfprot=0A#	fixe=
lfprot/DESCR=0A#	fixelfprot/Makefile=0A#	fixelfprot/PLIST=0A#	fixelfprot/fi=
les=0A#	fixelfprot/files/fixelfprot.c=0A#=0Aecho c - fixelfprot=0Amkdir -p =
fixelfprot > /dev/null 2>&1=0Aecho x - fixelfprot/DESCR=0Ased 's/^X//' >fix=
elfprot/DESCR << 'END-of-fixelfprot/DESCR'=0AXFix up the permission bits fo=
r the program load section containing section of a PPC ELF bina=
ry.=0AEND-of-fixelfprot/DESCR=0Aecho x - fixelfprot/Makefile=0Ased 's/^X//'=
 >fixelfprot/Makefile << 'END-of-fixelfprot/Makefile'=0AX# $NetBSD: Makefil=
e,v 1.29 2004/01/20 12:26:15 agc Exp $=0AX=0AXDISTNAME=3D	fixelfprot-200407=
mpty=0AX=0AXMAINTAINER=3D	http://mail-in=	C program to fi=
x ELF protection on .got table for PowerPC=0AX=0AXONLY_FOR_PLATFORM=3D	NetB=
SD-*-*=0AX=0AXPKG_INSTALLATION_TYPES=3D	overwrite pkgviews=0AX=0AXWRKSRC=3D=
		${WRKDIR}=0AXNO_CHECKSUM=3D	# defined=0AXNO_BUILDLINK=3D	# defined=0AXNO_=
CONFIGURE=3D	# defined=0AX=0AXINSTALLATION_DIRS=3D	bin=0AX=0AXdo-extract:=
=0AX	${CP} ${FILESDIR}/fixelfprot.c ${WRKSRC}=0AX=0AXdo-build:=0AX	cd ${WRK=
SRC} && ${CC} ${CFLAGS} fixelfprot.c -o fixelfprot=0AX=0AXdo-install:=0AX	$=
{INSTALL_PROGRAM} ${WRKSRC}/fixelfprot ${PREFIX}/sbin=0AX=0AX.include "../.=
./mk/"=0AEND-of-fixelfprot/Makefile=0Aecho x - fixelfprot/PLIST=
=0Ased 's/^X//' >fixelfprot/PLIST << 'END-of-fixelfprot/PLIST'=0AX@comment =
$NetBSD$=0AXsbin/fixelfprot=0AEND-of-fixelfprot/PLIST=0Aecho c - fixelfprot=
/files=0Amkdir -p fixelfprot/files > /dev/null 2>&1=0Aecho x - fixelfprot/f=
iles/fixelfprot.c=0Ased 's/^X//' >fixelfprot/files/fixelfprot.c << 'END-of-=
fixelfprot/files/fixelfprot.c'=0AX/*=0AX * Fix up the permission bits for t=
he program load section containing the=0AX * .got section of a PPC ELF bina=
ry.=0AX */=0AX=0AX#include <stdio.h>=0AX#include <err.h>=0AX#define ELFSIZE=
 32=0AX#include <sys/exec_elf.h>=0AX#include <sys/endian.h>=0AX#include <un=
istd.h>=0AX#include <stdlib.h>=0AX#include <fcntl.h>=0AX#include <string.h>=
=0AX=0AXvoid xlseek(int, off_t, int);=0AXvoid xread(int, void *, size_t);=
=0AXvoid xwrite(int, void *, size_t);=0AXvoid *xmalloc(size_t);=0AX=0AXvoid=
=0AXxlseek(int fd, off_t off, int whence)=0AX{=0AX	int rv;=0AX=0AX	rv =3D l=
seek(fd, off, whence);=0AX	if (rv < 0) {=0AX		err(1, "lseek");=0AX	}=0AX}=
=0AX=0AXvoid=0AXxread(int fd, void *buf, size_t size)=0AX{=0AX	int rv;=0AX=
=0AX	rv =3D read(fd, buf, size);=0AX	if (rv < 0) {=0AX		err(1, "read");=0AX=
	}=0AX	if (rv !=3D size) {=0AX		errx(1, "short read %d vs. %d", rv, size);=
=0AX	}=0AX}=0AX=0AXvoid=0AXxwrite(int fd, void *buf, size_t size)=0AX{=0AX	=
int rv;=0AX=0AX	rv =3D write(fd, buf, size);=0AX	if (rv < 0) {=0AX		err(1, =
"write");=0AX	}=0AX	if (rv !=3D size) {=0AX		errx(1, "short write %d vs. %d=
", rv, size);=0AX	}=0AX}=0AX=0AX=0AXvoid *=0AXxmalloc(size_t size)=0AX{=0AX=
	void *buf;=0AX=0AX	buf =3D malloc(size);=0AX	if (buf =3D=3D NULL) {=0AX		e=
rr(1, "malloc");=0AX	}=0AX	return buf;=0AX}=0AX=0AXint=0AXmain(int argc, ch=
ar **argv)=0AX{=0AX	Elf32_Ehdr eh;=0AX	Elf32_Phdr *ph;=0AX	Elf32_Shdr *sh;=
=0AX	Elf32_Addr gotaddr;=0AX	size_t phsize, shsize, strsize;=0AX	char *strb=
uf;=0AX	int fd, i, idx;=0AX=0AX	/*=0AX	 * Check arguments and open the file=
.=0AX	 */=0AX=0AX	if (argc !=3D 2) {=0AX		errx(1, "usage: %s <file>", getpr=
ogname());=0AX	}=0AX	fd =3D open(argv[1], O_RDWR);=0AX	if (fd < 0) {=0AX		e=
rr(1, "open %s", argv[1]);=0AX	}=0AX=0AX	/*=0AX	 * Read and validate the EL=
F header.=0AX	 */=0AX=0AX	xread(fd, &eh, sizeof (eh));=0AX	if (memcmp(eh.e_=
ident, ELFMAG, SELFMAG) !=3D 0 ||=0AX	    eh.e_ident[EI_CLASS] !=3D ELFCLAS=
S) {=0AX		errx(1, "not an ELF file");=0AX	}=0AX	if (be16toh(eh.e_machine) !=
=3D EM_PPC) {=0AX		errx(1, "ELF file is wrong architecture");=0AX	}=0AX	if =
(be16toh(eh.e_type) !=3D ET_EXEC) {=0AX		errx(1, "ELF file is not an execut=
able");=0AX	}=0AX	if (be16toh(eh.e_shnum) > 512 || be16toh(eh.e_phnum) > 12=
8) {=0AX		errx(1, "ELF file has too many sections");=0AX	}=0AX	if (be16toh(=
eh.e_shstrndx) >=3D be16toh(eh.e_shnum)) {=0AX		errx(1, "string table index=
 out of range");=0AX	}=0AX=0AX	/*=0AX	 * Read the program headers, section =
headers and string table.=0AX	 */=0AX=0AX	phsize =3D be16toh(eh.e_phnum) * =
sizeof(Elf_Phdr);=0AX	ph =3D xmalloc(phsize);=0AX	xlseek(fd, (off_t)be32toh=
(eh.e_phoff), SEEK_SET);=0AX	xread(fd, ph, phsize);=0AX=0AX	shsize =3D be16=
toh(eh.e_shnum) * sizeof(Elf_Shdr);=0AX	sh =3D xmalloc(shsize);=0AX	xlseek(=
fd, (off_t)be32toh(eh.e_shoff), SEEK_SET);=0AX	xread(fd, sh, shsize);=0AX=
=0AX	idx =3D be16toh(eh.e_shstrndx);=0AX	strsize =3D be32toh(sh[idx].sh_siz=
e);=0AX	strbuf =3D xmalloc(strsize);=0AX	xlseek(fd, (off_t)be32toh(sh[idx].=
sh_offset), SEEK_SET);=0AX	xread(fd, strbuf, strsize);=0AX=0AX	/*=0AX	 * Fi=
nd the .got section.=0AX	 */=0AX=0AX	gotaddr =3D 0;=0AX	for (i =3D 0; i < b=
e16toh(eh.e_shnum); i++) {=0AX		if (strcmp(&strbuf[be32toh(sh[i].sh_name)],=
 ".got") =3D=3D 0) {=0AX			gotaddr =3D be32toh(sh[i].sh_addr);=0AX			break;=
=0AX		}=0AX	}=0AX	if (gotaddr =3D=3D 0) {=0AX		errx(1, "couldn't find the .=
got section");=0AX	}=0AX=0AX	/*=0AX	 * Find the program header load section=
 containing the .got section.=0AX	 */=0AX=0AX	idx =3D -1;=0AX	for (i =3D 0;=
 i < be16toh(eh.e_phnum); i++) {=0AX		if (be32toh(ph[i].p_type) =3D=3D PT_L=
OAD &&=0AX		    gotaddr >=3D be32toh(ph[i].p_vaddr) &&=0AX		    gotaddr < b=
e32toh(ph[i].p_vaddr) + be32toh(ph[i].p_memsz)) {=0AX			idx =3D i;=0AX		}=
=0AX	}=0AX	if (idx =3D=3D -1) {=0AX		errx(1, "couldn't find program header =
for .got");=0AX	}=0AX	if (be32toh(ph[idx].p_flags) & PF_X) {=0AX		errx(1, "=
permission bits already include execute");=0AX	}=0AX=0AX	/*=0AX	 * Add exec=
ute permission and write back the entry.=0AX	 */=0AX=0AX	ph[idx].p_flags |=
=3D be32toh(PF_X);=0AX	xlseek(fd, (off_t)be32toh(eh.e_phoff), SEEK_SET);=0A=
X	xwrite(fd, ph, phsize);=0AX=0AX	errx(0, "execute permission added");=0AX	=