From aa030b42b7df7b2af8d61e48fce99cdf4e9125fb Mon Sep 17 00:00:00 2001 From: Minero Aoki Date: Sun, 16 Nov 2008 11:01:10 +0000 Subject: [PATCH] * net/loveruby/cflat/compiler/CodeGenerator.java: should access file-local gvar directly (with @GOTOFF) in PIE. * net/loveruby/cflat/ast/Entity.java: all entities should have memref or address. * net/loveruby/cflat/ast/Variable.java: ditto. * net/loveruby/cflat/ast/DefinedVariable.java: ditto. * net/loveruby/cflat/ast/UndefinedVariable.java: ditto. * net/loveruby/cflat/ast/Function.java: ditto. * net/loveruby/cflat/ast/DefinedFunction.java: ditto. * import/stdlib.hb: add new declarations. * import/unistd.hb: add new declarations. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4082 1b9489fe-b721-0410-924e-b54b9192deb8 --- ChangeLog | 22 ++++++ ToDo | 2 +- import/stdlib.hb | 8 +++ import/unistd.hb | 1 + net/loveruby/cflat/ast/DefinedFunction.java | 2 - net/loveruby/cflat/ast/DefinedVariable.java | 10 --- net/loveruby/cflat/ast/Entity.java | 32 +++++++-- net/loveruby/cflat/ast/Function.java | 41 +++--------- net/loveruby/cflat/ast/UndefinedVariable.java | 4 -- net/loveruby/cflat/ast/Variable.java | 31 --------- .../cflat/compiler/CodeGenerator.java | 67 +++++++++---------- 11 files changed, 102 insertions(+), 118 deletions(-) diff --git a/ChangeLog b/ChangeLog index d902108..6a5b3a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +Sun Nov 16 20:01:06 2008 Minero Aoki + + * net/loveruby/cflat/compiler/CodeGenerator.java: should access + file-local gvar directly (with @GOTOFF) in PIE. + + * net/loveruby/cflat/ast/Entity.java: all entities should have + memref or address. + + * net/loveruby/cflat/ast/Variable.java: ditto. + + * net/loveruby/cflat/ast/DefinedVariable.java: ditto. + + * net/loveruby/cflat/ast/UndefinedVariable.java: ditto. + + * net/loveruby/cflat/ast/Function.java: ditto. + + * net/loveruby/cflat/ast/DefinedFunction.java: ditto. + + * import/stdlib.hb: add new declarations. + + * import/unistd.hb: add new declarations. + Sun Nov 2 18:27:01 2008 Minero Aoki * net/loveruby/cflat/compiler/Options.java: new option diff --git a/ToDo b/ToDo index 9f62003..5ba38de 100644 --- a/ToDo +++ b/ToDo @@ -6,9 +6,9 @@ * "extern char*[] sys_errlist" is array, not pointer * &puts should be typed as int(*)(char*)*, not int(*)(char*)** * check opassign semantic as operator +* use enum for compiler mode. * -fPIE, -pie * implement difference against PIC -* remove all FIXME == Done diff --git a/import/stdlib.hb b/import/stdlib.hb index bd26177..9498a4f 100644 --- a/import/stdlib.hb +++ b/import/stdlib.hb @@ -1 +1,9 @@ +// stdlib.hb + +import stddef; // for size_t + extern void exit(int status); +extern void* calloc(size_t nmemb, size_t size); +extern void* malloc(size_t size); +extern void free(void* ptr); +extern void* realloc(void* ptr, size_t size); diff --git a/import/unistd.hb b/import/unistd.hb index 2fe302a..bfdc465 100644 --- a/import/unistd.hb +++ b/import/unistd.hb @@ -6,3 +6,4 @@ extern void _exit(int status); extern pid_t fork(void); extern pid_t getpid(void); extern pid_t getppid(void); +extern unsigned int sleep(unsigned int secs); diff --git a/net/loveruby/cflat/ast/DefinedFunction.java b/net/loveruby/cflat/ast/DefinedFunction.java index 141594c..97f5b22 100644 --- a/net/loveruby/cflat/ast/DefinedFunction.java +++ b/net/loveruby/cflat/ast/DefinedFunction.java @@ -1,8 +1,6 @@ package net.loveruby.cflat.ast; import net.loveruby.cflat.compiler.ErrorHandler; import net.loveruby.cflat.type.*; -import net.loveruby.cflat.asm.Symbol; -import net.loveruby.cflat.asm.BaseSymbol; import net.loveruby.cflat.asm.Label; import net.loveruby.cflat.exception.*; import java.util.*; diff --git a/net/loveruby/cflat/ast/DefinedVariable.java b/net/loveruby/cflat/ast/DefinedVariable.java index ef667c5..dcfb7eb 100644 --- a/net/loveruby/cflat/ast/DefinedVariable.java +++ b/net/loveruby/cflat/ast/DefinedVariable.java @@ -23,16 +23,6 @@ public class DefinedVariable extends Variable { this.sequence = seq; } - public Symbol symbol() { - if (symbol != null) { - return symbol; - } - else { - symbol = new NamedSymbol(symbolString()); - return symbol; - } - } - public String symbolString() { return (sequence < 0) ? name : (name + "." + sequence); } diff --git a/net/loveruby/cflat/ast/Entity.java b/net/loveruby/cflat/ast/Entity.java index 6bae4b0..12d3254 100644 --- a/net/loveruby/cflat/ast/Entity.java +++ b/net/loveruby/cflat/ast/Entity.java @@ -1,7 +1,6 @@ package net.loveruby.cflat.ast; import net.loveruby.cflat.type.*; import net.loveruby.cflat.asm.Symbol; -import net.loveruby.cflat.asm.NamedSymbol; import net.loveruby.cflat.asm.AsmOperand; import net.loveruby.cflat.asm.MemoryReference; @@ -10,6 +9,8 @@ abstract public class Entity extends Node { protected boolean isPrivate; protected TypeNode typeNode; protected long nRefered; + protected MemoryReference memref; + protected MemoryReference address; public Entity(boolean priv, TypeNode type, String name) { this.name = name; @@ -22,8 +23,8 @@ abstract public class Entity extends Node { return name; } - public Symbol symbol() { - return new NamedSymbol(name); + public String symbolString() { + return name(); } abstract public boolean isDefined(); @@ -61,8 +62,29 @@ abstract public class Entity extends Node { abstract public boolean cannotLoad(); - abstract public MemoryReference memref(); - abstract public AsmOperand address(); + public void setMemref(MemoryReference mem) { + this.memref = mem; + } + + public MemoryReference memref() { + checkAddress(); + return memref; + } + + public void setAddress(MemoryReference mem) { + this.address = mem; + } + + public AsmOperand address() { + checkAddress(); + return address; + } + + protected void checkAddress() { + if (memref == null && address == null) { + throw new Error("address did not resolved: " + name); + } + } public Location location() { return typeNode.location(); diff --git a/net/loveruby/cflat/ast/Function.java b/net/loveruby/cflat/ast/Function.java index 403a27c..103709a 100644 --- a/net/loveruby/cflat/ast/Function.java +++ b/net/loveruby/cflat/ast/Function.java @@ -1,16 +1,12 @@ package net.loveruby.cflat.ast; import net.loveruby.cflat.type.*; -import net.loveruby.cflat.asm.Label; import net.loveruby.cflat.asm.Symbol; -import net.loveruby.cflat.asm.NamedSymbol; -import net.loveruby.cflat.asm.AsmOperand; -import net.loveruby.cflat.asm.MemoryReference; +import net.loveruby.cflat.asm.Label; import java.util.*; abstract public class Function extends Entity { - protected Symbol symbol; + protected Symbol callingSymbol; protected Label label; - protected AsmOperand address; public Function(boolean priv, TypeNode t, String name) { super(priv, t, name); @@ -37,18 +33,18 @@ abstract public class Function extends Entity { return true; } - public void setSymbol(Symbol sym) { - if (this.symbol != null) { - throw new Error("must not happen: Function#symbol was set again"); + public void setCallingSymbol(Symbol sym) { + if (this.callingSymbol != null) { + throw new Error("must not happen: Function#callingSymbol was set again"); } - this.symbol = sym; + this.callingSymbol = sym; } - public Symbol symbol() { - if (this.symbol == null) { - throw new Error("must not happen: Function#symbol called but null"); + public Symbol callingSymbol() { + if (this.callingSymbol == null) { + throw new Error("must not happen: Function#callingSymbol called but null"); } - return this.symbol; + return this.callingSymbol; } public Label label() { @@ -56,22 +52,7 @@ abstract public class Function extends Entity { return label; } else { - return label = new Label(symbol()); + return label = new Label(callingSymbol()); } } - - public MemoryReference memref() { - return null; - } - - public void setAddress(AsmOperand addr) { - this.address = addr; - } - - public AsmOperand address() { - if (address == null) { - throw new Error("must not happen: Function.address == null"); - } - return this.address; - } } diff --git a/net/loveruby/cflat/ast/UndefinedVariable.java b/net/loveruby/cflat/ast/UndefinedVariable.java index c733952..acdd4a9 100644 --- a/net/loveruby/cflat/ast/UndefinedVariable.java +++ b/net/loveruby/cflat/ast/UndefinedVariable.java @@ -10,10 +10,6 @@ public class UndefinedVariable extends Variable { public boolean isPrivate() { return false; } public boolean isInitialized() { return false; } - public String symbolString() { - return name(); - } - protected void _dump(Dumper d) { d.printMember("name", name); d.printMember("isPrivate", isPrivate()); diff --git a/net/loveruby/cflat/ast/Variable.java b/net/loveruby/cflat/ast/Variable.java index ee2002f..c547ea4 100644 --- a/net/loveruby/cflat/ast/Variable.java +++ b/net/loveruby/cflat/ast/Variable.java @@ -1,43 +1,12 @@ package net.loveruby.cflat.ast; import net.loveruby.cflat.type.*; -import net.loveruby.cflat.asm.AsmOperand; -import net.loveruby.cflat.asm.MemoryReference; abstract public class Variable extends Entity { - protected MemoryReference memref; - protected MemoryReference address; - public Variable(boolean priv, TypeNode type, String name) { super(priv, type, name); } - abstract public String symbolString(); - public boolean cannotLoad() { return type().isAllocatedArray(); } - - public void setMemref(MemoryReference mem) { - this.memref = mem; - } - - public MemoryReference memref() { - checkAddress(); - return memref; - } - - public void setAddress(MemoryReference mem) { - this.address = mem; - } - - public AsmOperand address() { - checkAddress(); - return address; - } - - protected void checkAddress() { - if (memref == null && address == null) { - throw new Error("address did not resolved: " + name); - } - } } diff --git a/net/loveruby/cflat/compiler/CodeGenerator.java b/net/loveruby/cflat/compiler/CodeGenerator.java index 110f62f..55d95b4 100644 --- a/net/loveruby/cflat/compiler/CodeGenerator.java +++ b/net/loveruby/cflat/compiler/CodeGenerator.java @@ -81,7 +81,7 @@ public class CodeGenerator compileCommonSymbol(var); } // others - if (options.isPICRequired()) { + if (options.isPositionIndependent()) { PICThunk(GOTBaseReg()); } } @@ -89,7 +89,7 @@ public class CodeGenerator protected void locateConstant(ConstantEntry ent, SymbolTable symbols) { ent.setSymbol(symbols.newSymbol()); - if (options.isPICRequired()) { + if (options.isPositionIndependent()) { Symbol offset = localGOTSymbol(ent.symbol()); ent.setMemref(mem(offset, GOTBaseReg())); } @@ -99,52 +99,49 @@ public class CodeGenerator } } - protected void locateGlobalVariable(Variable var) { - MemoryReference mem; - if (options.isPICRequired()) { - if (var.isPrivate()) { - mem = mem(localGOTSymbol(var.symbol()), GOTBaseReg()); - var.setMemref(mem); + protected void locateGlobalVariable(Entity ent) { + Symbol sym = ent.isPrivate() ? privateSymbol(ent.symbolString()) + : globalSymbol(ent.symbolString()); + if (options.isPositionIndependent()) { + MemoryReference mem; + if (ent.isPrivate() || optimizeGvarAccess(ent)) { + mem = mem(localGOTSymbol(sym), GOTBaseReg()); + ent.setMemref(mem); } else { - mem = mem(globalGOTSymbol(var.symbol()), GOTBaseReg()); - var.setAddress(mem); + mem = mem(globalGOTSymbol(sym), GOTBaseReg()); + ent.setAddress(mem); } } else { - mem = mem(globalSymbol(var.symbolString())); - var.setMemref(mem); + ent.setMemref(mem(sym)); } } protected void locateFunction(Function func) { - func.setSymbol(functionSymbol(func)); - func.setAddress(functionAddress(func)); + func.setCallingSymbol(callingSymbol(func)); + locateGlobalVariable(func); } - protected Symbol functionSymbol(Function func) { - if (func.isDefined()) { - return globalSymbol(func.name()); + protected Symbol callingSymbol(Function func) { + if (func.isPrivate()) { + return privateSymbol(func.symbolString()); } else { - Symbol sym = privateSymbol(func.name()); - return options.isPICRequired() ? PLTSymbol(sym) : sym; + Symbol sym = globalSymbol(func.symbolString()); + return doesIndirectAccess(func) ? PLTSymbol(sym) : sym; } } - protected AsmOperand functionAddress(Function func) { - Symbol sym = new NamedSymbol(func.name()); - if (options.isPICRequired()) { - if (func.isPrivate()) { - return mem(localGOTSymbol(sym), GOTBaseReg()); - } - else { - return mem(globalGOTSymbol(sym), GOTBaseReg()); - } - } - else { - return imm(sym); - } + // condition to use indirect access (using PLT to call, GOT to refer). + // In PIC, we do use indirect access for all global variables. + // In PIE, we do use direct access for file-local reference. + protected boolean doesIndirectAccess(Entity ent) { + return options.isPositionIndependent() && !optimizeGvarAccess(ent); + } + + protected boolean optimizeGvarAccess(Entity ent) { + return options.isPIERequired() && ent.isDefined(); } /** Generates initialized entries */ @@ -225,7 +222,7 @@ public class CodeGenerator // #@@} // - // PIC related constants and codes + // PIC/PIE related constants and codes // static protected final Symbol GOT = new NamedSymbol("_GLOBAL_OFFSET_TABLE_"); @@ -314,7 +311,7 @@ public class CodeGenerator long lvarBytes = allocateLocalVariables(func.body().scope(), saveRegs.size()); prologue(func, saveRegs, lvarBytes); - if (options.isPICRequired() && stats.doesRegisterUsed(GOTBaseReg())) { + if (options.isPositionIndependent() && stats.doesRegisterUsed(GOTBaseReg())) { loadGOTBaseAddress(GOTBaseReg()); } as.addAll(bodyAsms); @@ -551,7 +548,7 @@ public class CodeGenerator // call if (node.isStaticCall()) { // call via function name - call(node.function().symbol()); + call(node.function().callingSymbol()); } else { // call via pointer