Minimally fix pcc for powerpc

This unbreaks the powerpc package of lang/pcc/pcc-libs and puts enough
fixes in lang/pcc/pcc for powerpc to compile the simplest C program,

$ cat hello.c
#include <stdio.h>
int main(void) { puts("Hello, BSD!"); return 0; }
$ pcc -O2 -o hello hello.c

It can't compile much more; pcc's powerpc code generator still fails
with static function calls and with floating-point literals.

ok sthen@
This commit is contained in:
gkoehler 2022-10-28 20:47:06 +00:00
parent 3641fee99f
commit 7f7f3e63ec
9 changed files with 247 additions and 2 deletions

View File

@ -2,7 +2,7 @@ COMMENT = libraries for the portable C compiler
DISTNAME = pcc-libs-${DISTVER}
PKGNAME = pcc-libs-${PKGVER}
REVISION = 2
REVISION = 3
MASTER_SITES = http://pcc.ludd.ltu.se/ftp/pub/pcc-libs/ \
ftp://pcc.ludd.ltu.se/pub/pcc-libs/

View File

@ -0,0 +1,37 @@
Allow powerpc to compile this file.
Index: libpcc/cxmuldiv.c
--- libpcc/cxmuldiv.c.orig
+++ libpcc/cxmuldiv.c
@@ -402,6 +402,23 @@ __muldc3(double fa, double fb, double fc, double fd)
return ux.f + 1.0iF * uy.f;
}
+#if defined(mach_powerpc)
+/* Long double is double. */
+
+long double _Complex
+__divxc3(long double ax, long double bx, long double cx, long double dx)
+{
+ return __divdc3(ax, bx, cx, dx);
+}
+
+long double _Complex
+__mulxc3(long double fa, long double fb, long double fc, long double fd)
+{
+ return __mulxc3(fa, fb, fc, fd);
+}
+
+#else
+
/*
* Long double functions.
*/
@@ -618,5 +635,7 @@ __mulxc3(long double fa, long double fb, long double f
}
return ux.f + 1.0iF * uy.f;
}
+
+#endif
#endif

View File

@ -0,0 +1,21 @@
Don't #include <machine/endian.h>, because its macro __weak_alias
isn't compatible with NetBSD, but causes a compiler error in
fpgetround.c under #ifdef __weak_alias.
Index: libsoftfloat/arch/powerpc/powerpc-gcc.h
--- libsoftfloat/arch/powerpc/powerpc-gcc.h.orig
+++ libsoftfloat/arch/powerpc/powerpc-gcc.h
@@ -5,11 +5,10 @@
One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
-------------------------------------------------------------------------------
*/
-#include <machine/endian.h>
-#if _BYTE_ORDER == _BIG_ENDIAN
+#ifdef __BIG_ENDIAN__
#define BIGENDIAN
#endif
-#if _BYTE_ORDER == _LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN__
#define LITTLEENDIAN
#endif

View File

@ -2,6 +2,7 @@ COMMENT = portable C compiler
DISTNAME = pcc-${DISTVER}
PKGNAME = pcc-${PKGVER}
REVISION = 0
WANTLIB += c

View File

@ -0,0 +1,45 @@
Emit code for the secure PLT, where r30 must point to the global
offset table.
Add a shape SGOTCON to emit code like "lwz %r3,.L459@got(30)" for
loading a constant address from the global offset table. This fixes
string literals in PIC.
Index: arch/powerpc/local2.c
--- arch/powerpc/local2.c.orig
+++ arch/powerpc/local2.c
@@ -143,8 +143,21 @@ prologue(struct interpass_prolog *ipp)
if (kflag) {
#if defined(ELFABI)
+#if 0 /* BSS PLT */
printf("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n");
printf("\tmflr %s\n", rnames[GOTREG]);
+#else /* secure PLT */
+ const char *gotreg = rnames[GOTREG];
+ int lab = getlab2();
+
+ printf("\tbcl 20,31," LABFMT "\n", lab);
+ deflab(lab);
+ printf("\tmflr %s\n", gotreg);
+ printf("\taddis %s,%s,_GLOBAL_OFFSET_TABLE_-" LABFMT "@ha\n",
+ gotreg, gotreg, lab);
+ printf("\taddi %s,%s,_GLOBAL_OFFSET_TABLE_-" LABFMT "@l\n",
+ gotreg, gotreg, lab);
+#endif
#elif defined(MACHOABI)
printf("\tbcl 20,31,L%s$pb\n", ipp->ipp_name + 1);
printf("L%s$pb:\n", ipp->ipp_name + 1);
@@ -1473,6 +1486,12 @@ special(NODE *p, int shape)
case SPCON:
if (o == ICON && p->n_name[0] == 0 && (getlval(p) & ~0x7fff) == 0)
return SRDIR;
+ break;
+ case SGOTCON:
+#if defined(ELFABI)
+ if (o == ICON && strstr(p->n_name, "@got(30)"))
+ return SRDIR;
+#endif
break;
}
return SRNOPE;

View File

@ -0,0 +1,57 @@
Set more members of struct symtab, by copying code from i386 and m68k.
This prevents SIGSEGV from an uninitialized sp->sap, and sets SASG so
string literals don't go missing.
Emit code for the secure PLT, where r30 must point to the global
offset table.
Index: arch/powerpc/local.c
--- arch/powerpc/local.c.orig
+++ arch/powerpc/local.c
@@ -87,9 +87,11 @@ picsymtab(char *p, char *s, char *s2)
strlcpy(sp->sname, p, len);
strlcat(sp->sname, s, len);
strlcat(sp->sname, s2, len);
+ sp->sap = attr_new(ATTR_SONAME, 1);
+ sp->sap->sarg(0) = sp->sname;
sp->sclass = EXTERN;
sp->sflags = sp->slevel = 0;
-
+ sp->stype = 0xdeadbeef;
return sp;
}
@@ -112,7 +114,7 @@ picext(NODE *p)
#if defined(ELFABI)
- sp = picsymtab("", name, "@got(31)");
+ sp = picsymtab("", name, "@got(30)");
q = xbcon(0, sp, PTR+VOID);
q = block(UMUL, q, 0, PTR+VOID, 0, 0);
@@ -168,11 +170,13 @@ picstatic(NODE *p)
if (p->n_sp->slevel > 0) {
char buf[64];
+ if ((p->n_sp->sflags & SMASK) == SSTRING)
+ p->n_sp->sflags |= SASG;
snprintf(buf, 64, LABFMT, (int)p->n_sp->soffset);
- sp = picsymtab("", buf, "@got(31)");
+ sp = picsymtab("", buf, "@got(30)");
} else {
n = getexname(p->n_sp);
- sp = picsymtab("", n, "@got(31)");
+ sp = picsymtab("", n, "@got(30)");
}
sp->sclass = STATIC;
sp->stype = p->n_sp->stype;
@@ -626,7 +630,7 @@ fixnames(NODE *p, void *arg)
#if defined(ELFABI)
if ((ap2 = attr_find(sp->sap, ATTR_SONAME)) == NULL ||
- (c = strstr(ap2->sarg(0), "@got(31)")) == NULL)
+ (c = strstr(ap2->sarg(0), "@got(30)")) == NULL)
cerror("fixnames2");
if (isu) {
memcpy(c, "@plt", sizeof("@plt"));

View File

@ -0,0 +1,53 @@
Don't clobber ELF's thread pointer in r2.
Emit code for the secure PLT, where r30 must point to the global
offset table.
Add a shape SGOTCON to emit code like "lwz %r3,.L459@got(30)" for
loading a constant address from the global offset table. This fixes
string literals in PIC.
Index: arch/powerpc/macdefs.h
--- arch/powerpc/macdefs.h.orig
+++ arch/powerpc/macdefs.h
@@ -229,10 +229,16 @@ typedef long long OFFSZ;
#define NUMCLASS 3
#define MAXREGS 64 /* XXX cannot have more than 64 */
+#ifdef ELFABI
+#define RSTATUS_R2 0 /* Thread Pointer */
+#else
+#define RSTATUS_R2 (SAREG|TEMPREG)
+#endif
+
#define RSTATUS \
0, /* R0 */ \
0, /* R1 */ \
- SAREG|TEMPREG, /* R2 */ \
+ RSTATUS_R2, /* R2 */ \
SAREG|TEMPREG, /* R3 */ \
SAREG|TEMPREG, /* R4 */ \
SAREG|TEMPREG, /* R5 */ \
@@ -337,8 +343,14 @@ typedef long long OFFSZ;
* capable of running in this manner, and expects a frame pointer.
*/
#define SPREG R1 /* stack pointer */
+#if defined(ELFABI)
+/* Secure PLT needs got in r30. */
+#define GOTREG R30 /* global offset table (PIC) */
+#define FPREG R31 /* frame pointer */
+#elif defined(MACHOABI)
#define FPREG R30 /* frame pointer */
#define GOTREG R31 /* global offset table (PIC) */
+#endif
#ifdef FPREG
#define ARGINIT (24*8) /* # bits above fp where arguments start */
@@ -364,6 +376,7 @@ int retreg(int ty);
#define SHSTR (MAXSPECIAL+1) /* short struct */
#define SFUNCALL (MAXSPECIAL+2) /* struct assign after function call */
#define SPCON (MAXSPECIAL+3) /* positive constant */
+#define SGOTCON (MAXSPECIAL+4) /* constant in global offset table */
int features(int f);
#define FEATURE_BIGENDIAN 0x00010000

View File

@ -0,0 +1,22 @@
Add a shape SGOTCON to emit code like "lwz %r3,.L459@got(30)" for
loading a constant address from the global offset table. This fixes
string literals in PIC.
Index: arch/powerpc/table.c
--- arch/powerpc/table.c.orig
+++ arch/powerpc/table.c
@@ -745,6 +745,14 @@ struct optab table[] = {
* The next rules takes care of assignments. "=".
*/
+#if defined(ELFABI)
+{ ASSIGN, FOREFF|INAREG,
+ SAREG, TWORD|TPOINT,
+ SGOTCON, TANY,
+ 0, RDEST,
+ " lwz AL,AR" COM "elfabi got constant" "\n", },
+#endif
+
{ ASSIGN, FOREFF|INAREG,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SSCON, TANY,

View File

@ -1,7 +1,7 @@
Index: cc/cc/cc.c
--- cc/cc/cc.c.orig
+++ cc/cc/cc.c
@@ -1801,7 +1801,7 @@ static char *gcppflags[] = {
@@ -1829,7 +1829,7 @@ static char *gcppflags[] = {
#ifndef os_win32
#ifdef GCC_COMPAT
"-D__GNUC__=4",
@ -10,3 +10,12 @@ Index: cc/cc/cc.c
"-D__GNUC_PATCHLEVEL__=1",
"-D__REGISTER_PREFIX__=" REGISTER_PREFIX,
"-D__USER_LABEL_PREFIX__=" USER_LABEL_PREFIX,
@@ -2016,7 +2016,7 @@ struct flgcheck asflgcheck[] = {
#if !defined(USE_YASM) && !defined(NO_AS_V)
{ &vflag, 1, "-v" },
#endif
-#if defined(os_openbsd) && defined(mach_mips64)
+#if defined(os_openbsd) && (defined(mach_mips64) || defined(mach_powerpc))
{ &kflag, 1, "-KPIC" },
#else
{ &kflag, 1, "-k" },