Example #1
0
void CloneObjectsTest::testCloneMethod() {
    VMSymbol* methodSymbol = GetUniverse()->NewSymbol("myMethod");
    VMMethod* orig = GetUniverse()->NewMethod(methodSymbol, 0, 0);
    VMMethod* clone = orig->Clone();

    CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->objectSize, clone->objectSize);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfLocals differs!!",
            INT_VAL(load_ptr(orig->numberOfLocals)),
            INT_VAL(load_ptr(clone->numberOfLocals)));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("bcLength differs!!",
            INT_VAL(load_ptr(orig->bcLength)),
            INT_VAL(load_ptr(clone->bcLength)));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("maximumNumberOfStackElements differs!!",
            INT_VAL(load_ptr(orig->maximumNumberOfStackElements)),
            INT_VAL(load_ptr(clone->maximumNumberOfStackElements)));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfArguments differs!!",
            INT_VAL(load_ptr(orig->numberOfArguments)),
            INT_VAL(load_ptr(clone->numberOfArguments)));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfConstants differs!!",
            INT_VAL(load_ptr(orig->numberOfConstants)),
            INT_VAL(load_ptr(clone->numberOfConstants)));

    CPPUNIT_ASSERT_EQUAL_MESSAGE("GetHolder() differs!!", orig->GetHolder(), clone->GetHolder());
    CPPUNIT_ASSERT_EQUAL_MESSAGE("GetSignature() differs!!", orig->GetSignature(), clone->GetSignature());
}
Example #2
0
void _Symbol::Equal(VMObject*, VMFrame* frame) {
    vm_oop_t op1 = frame->Pop();
    vm_oop_t op2 = frame->Pop();
    
    if (op1 == op2) {
        frame->Push(load_ptr(trueObject));
    } else {
        frame->Push(load_ptr(falseObject));
    }
}
Example #3
0
void _System::HasGlobal_(Interpreter*, VMFrame* frame) {
    VMSymbol* arg = static_cast<VMSymbol*>(frame->Pop());
    frame->Pop(); // pop self (system)

    if (GetUniverse()->HasGlobal(arg)) {
        frame->Push(load_ptr(trueObject));
    } else {
        frame->Push(load_ptr(falseObject));
    }
}
Example #4
0
StdString VMObject::AsDebugString() const {
    if (this == load_ptr(nilObject)) {
        return "nilObject";
    } else if (this == load_ptr(trueObject)) {
        return "trueObject";
    } else if (this == load_ptr(falseObject)) {
        return "falseObject";
    }
    return "Object(" + GetClass()->GetName()->GetStdString() + ")";
}
Example #5
0
void Interpreter::WalkGlobals(walk_heap_fn walk) {
#warning method and frame are stored as VMptrs, is that acceptable? Is the solution here with _store_ptr and load_ptr robust?
    
    method = load_ptr(static_cast<GCMethod*>(walk(_store_ptr(method))));
    
    // Get the current frame and mark it.
    // Since marking is done recursively, this automatically
    // marks the whole stack
# warning Do I need a null check here?
    frame  = load_ptr(static_cast<GCFrame*>(walk(_store_ptr(frame))));
}
Example #6
0
void Universe::InitializeSystemClass(VMClass* systemClass,
VMClass* superClass, const char* name) {
    StdString s_name(name);

    if (superClass != nullptr) {
        systemClass->SetSuperClass(superClass);
        VMClass* sysClassClass = systemClass->GetClass();
        VMClass* superClassClass = superClass->GetClass();
        sysClassClass->SetSuperClass(superClassClass);
    } else {
        VMClass* sysClassClass = systemClass->GetClass();
        sysClassClass->SetSuperClass(load_ptr(classClass));
    }

    VMClass* sysClassClass = systemClass->GetClass();

    systemClass->SetInstanceFields(NewArray(0));
    sysClassClass->SetInstanceFields(NewArray(0));

    systemClass->SetInstanceInvokables(NewArray(0));
    sysClassClass->SetInstanceInvokables(NewArray(0));

    systemClass->SetName(SymbolFor(s_name));
    ostringstream Str;
    Str << s_name << " class";
    StdString classClassName(Str.str());
    sysClassClass->SetName(SymbolFor(classClassName));

    SetGlobal(systemClass->GetName(), systemClass);
}
Example #7
0
VMPrimitive::VMPrimitive(VMSymbol* signature) : VMInvokable(VMPrimitiveNumberOfFields) {
    //the only class that explicitly does this.
    SetClass(load_ptr(primitiveClass));
    SetSignature(signature);
    routine = nullptr;
    empty = false;
}
Example #8
0
void CloneObjectsTest::testCloneClass() {
    VMClass* orig = GetUniverse()->NewClass(load_ptr(integerClass));
    orig->SetName(GetUniverse()->NewSymbol("MyClass"));
    orig->SetSuperClass(load_ptr(doubleClass));
    orig->SetInstanceFields(GetUniverse()->NewArray(2));
    orig->SetInstanceInvokables(GetUniverse()->NewArray(4));
    VMClass* clone = orig->Clone();

    CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->objectSize, clone->objectSize);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("superClass differs!!", orig->superClass, clone->superClass);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("name differs!!", orig->name, clone->name);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceFields differs!!", orig->instanceFields, clone->instanceFields);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceInvokables differs!!", orig->instanceInvokables, clone->instanceInvokables);
}
Example #9
0
void _System::Global_(Interpreter*, VMFrame* frame) {
    VMSymbol* arg = static_cast<VMSymbol*>(frame->Pop());
    /*VMObject* self = */
    frame->Pop();
    vm_oop_t result = GetUniverse()->GetGlobal(arg);

    frame->Push(result ? result : load_ptr(nilObject));
}
Example #10
0
vm_oop_t Universe::GetGlobal(VMSymbol* name) {
    # warning is _store_ptr correct here? it relies on _store_ptr not to be really changed...
    auto it = globals.find(_store_ptr(name));
    if (it == globals.end()) {
        return nullptr;
    } else {
        return load_ptr(it->second);
    }
}
Example #11
0
void _System::Load_(Interpreter*, VMFrame* frame) {
    VMSymbol* arg = static_cast<VMSymbol*>(frame->Pop());
    frame->Pop();
    VMClass* result = GetUniverse()->LoadClass(arg);
    if (result)
        frame->Push(result);
    else
        frame->Push(load_ptr(nilObject));
}
Example #12
0
StdString VMMethod::AsDebugString() const {
    VMClass* holder = GetHolder();
    StdString holder_str;
    if (holder == load_ptr(nilObject)) {
        holder_str = "nil";
    } else {
        holder_str = holder->GetName()->GetStdString();
    }
    return "Method(" + holder_str + ">>#" + GetSignature()->GetStdString() + ")";
}
Example #13
0
VMClass* Universe::GetBlockClassWithArgs(long numberOfArguments) {
    map<long, GCClass*>::iterator it =
    blockClassesByNoOfArgs.find(numberOfArguments);
    if (it != blockClassesByNoOfArgs.end())
        return load_ptr(it->second);

    Assert(numberOfArguments < 10);

    ostringstream Str;
    Str << "Block" << numberOfArguments;
    VMSymbol* name = SymbolFor(Str.str());
    VMClass* result = LoadClassBasic(name, nullptr);

    result->AddInstancePrimitive(new (GetHeap<HEAP_CLS>()) VMEvaluationPrimitive(numberOfArguments) );

    SetGlobal(name, result);
# warning is _store_ptr sufficient here?
    blockClassesByNoOfArgs[numberOfArguments] = _store_ptr(result);

    return result;
}
Example #14
0
void Interpreter::doPushBlock(long bytecodeIndex) {
    // Short cut the negative case of #ifTrue: and #ifFalse:
    if (currentBytecodes[bytecodeIndexGlobal] == BC_SEND) {
        if (GetFrame()->GetStackElement(0) == load_ptr(falseObject) &&
            method->GetConstant(bytecodeIndexGlobal) == load_ptr(symbolIfTrue)) {
            GetFrame()->Push(load_ptr(nilObject));
            return;
        } else if (GetFrame()->GetStackElement(0) == load_ptr(trueObject) &&
                   method->GetConstant(bytecodeIndexGlobal) == load_ptr(symbolIfFalse)) {
            GetFrame()->Push(load_ptr(nilObject));
            return;
        }
    }

    VMMethod* blockMethod = static_cast<VMMethod*>(method->GetConstant(bytecodeIndex));

    long numOfArgs = blockMethod->GetNumberOfArguments();

    GetFrame()->Push(GetUniverse()->NewBlock(blockMethod, GetFrame(), numOfArgs));
}
Example #15
0
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
    RtldLockState *lockstate)
{
	const Elf_Rel *rel;
	const Elf_Rel *rellim;
	Elf_Addr *got = obj->pltgot;
	const Elf_Sym *sym, *def;
	const Obj_Entry *defobj;
	Elf_Word i;
#ifdef SUPPORT_OLD_BROKEN_LD
	int broken;
#endif

	/* The relocation for the dynamic loader has already been done. */
	if (obj == obj_rtld)
		return (0);

	if ((flags & SYMLOOK_IFUNC) != 0)
		/* XXX not implemented */
		return (0);

#ifdef SUPPORT_OLD_BROKEN_LD
	broken = 0;
	sym = obj->symtab;
	for (i = 1; i < 12; i++)
		if (sym[i].st_info == ELF_ST_INFO(STB_LOCAL, STT_NOTYPE))
			broken = 1;
	dbg("%s: broken=%d", obj->path, broken);
#endif

	i = (got[1] & GOT1_MASK) ? 2 : 1;

	/* Relocate the local GOT entries */
	got += i;
	dbg("got:%p for %d entries adding %p",
	    got, obj->local_gotno, obj->relocbase);
	for (; i < obj->local_gotno; i++) {
		*got += (Elf_Addr)obj->relocbase;
		got++;
	}
	sym = obj->symtab + obj->gotsym;

	dbg("got:%p for %d entries",
	    got, obj->symtabno);
	/* Now do the global GOT entries */
	for (i = obj->gotsym; i < obj->symtabno; i++) {
		dbg(" doing got %d sym %p (%s, %lx)", i - obj->gotsym, sym,
		    sym->st_name + obj->strtab, (u_long) *got);

#ifdef SUPPORT_OLD_BROKEN_LD
		if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
		    broken && sym->st_shndx == SHN_UNDEF) {
			/*
			 * XXX DANGER WILL ROBINSON!
			 * You might think this is stupid, as it intentionally
			 * defeats lazy binding -- and you'd be right.
			 * Unfortunately, for lazy binding to work right, we
			 * need to a way to force the GOT slots used for
			 * function pointers to be resolved immediately.  This
			 * is supposed to be done automatically by the linker,
			 * by not outputting a PLT slot and setting st_value
			 * to 0 if there are non-PLT references, but older
			 * versions of GNU ld do not do this.
			 */
			def = find_symdef(i, obj, &defobj, flags, NULL,
			    lockstate);
			if (def == NULL)
				return -1;
			*got = def->st_value + (Elf_Addr)defobj->relocbase;
		} else
#endif
		if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
		    sym->st_value != 0 && sym->st_shndx == SHN_UNDEF) {
			/*
			 * If there are non-PLT references to the function,
			 * st_value should be 0, forcing us to resolve the
			 * address immediately.
			 *
			 * XXX DANGER WILL ROBINSON!
			 * The linker is not outputting PLT slots for calls to
			 * functions that are defined in the same shared
			 * library.  This is a bug, because it can screw up
			 * link ordering rules if the symbol is defined in
			 * more than one module.  For now, if there is a
			 * definition, we fail the test above and force a full
			 * symbol lookup.  This means that all intra-module
			 * calls are bound immediately.  - mycroft, 2003/09/24
			 */
			*got = sym->st_value + (Elf_Addr)obj->relocbase;
			if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
				dbg("Warning2, i:%d maps to relocbase address:%p",
				    i, obj->relocbase);
			}

		} else if (sym->st_info == ELF_ST_INFO(STB_GLOBAL, STT_SECTION)) {
			/* Symbols with index SHN_ABS are not relocated. */
			if (sym->st_shndx != SHN_ABS) {
				*got = sym->st_value +
				    (Elf_Addr)obj->relocbase;
				if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
					dbg("Warning3, i:%d maps to relocbase address:%p",
					    i, obj->relocbase);
				}
			}
		} else {
			/* TODO: add cache here */
			def = find_symdef(i, obj, &defobj, flags, NULL,
			    lockstate);
			if (def == NULL) {
				dbg("Warning4, can't find symbole %d", i);
				return -1;
			}
			*got = def->st_value + (Elf_Addr)defobj->relocbase;
			if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
				dbg("Warning4, i:%d maps to relocbase address:%p",
				    i, obj->relocbase);
				dbg("via first obj symbol %s",
				    obj->strtab + obj->symtab[i].st_name);
				dbg("found in obj %p:%s",
				    defobj, defobj->path);
			}
		}

		dbg("  --> now %lx", (u_long) *got);
		++sym;
		++got;
	}

	got = obj->pltgot;
	rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
	for (rel = obj->rel; rel < rellim; rel++) {
		Elf_Word	r_symndx, r_type;
		void		*where;

		where = obj->relocbase + rel->r_offset;
		r_symndx = ELF_R_SYM(rel->r_info);
		r_type = ELF_R_TYPE(rel->r_info);

		switch (r_type & 0xff) {
		case R_TYPE(NONE):
			break;

		case R_TYPE(REL32): {
			/* 32-bit PC-relative reference */
			const size_t rlen =
			    ELF_R_NXTTYPE_64_P(r_type)
				? sizeof(Elf_Sxword)
				: sizeof(Elf_Sword);
			Elf_Sxword old = load_ptr(where, rlen);
			Elf_Sxword val = old;

			def = obj->symtab + r_symndx;

			if (r_symndx >= obj->gotsym) {
				val += got[obj->local_gotno + r_symndx - obj->gotsym];
				dbg("REL32/G(%p) %p --> %p (%s) in %s",
				    where, (void *)old, (void *)val,
				    obj->strtab + def->st_name,
				    obj->path);
			} else {
				/*
				 * XXX: ABI DIFFERENCE!
				 *
				 * Old NetBSD binutils would generate shared
				 * libs with section-relative relocations being
				 * already adjusted for the start address of
				 * the section.
				 *
				 * New binutils, OTOH, generate shared libs
				 * with the same relocations being based at
				 * zero, so we need to add in the start address
				 * of the section.
				 *
				 * --rkb, Oct 6, 2001
				 */

				if (def->st_info ==
				    ELF_ST_INFO(STB_LOCAL, STT_SECTION)
#ifdef SUPPORT_OLD_BROKEN_LD
				    && !broken
#endif
				    )
					val += (Elf_Addr)def->st_value;

				val += (Elf_Addr)obj->relocbase;

				dbg("REL32/L(%p) %p -> %p (%s) in %s",
				    where, (void *)old, (void *)val,
				    obj->strtab + def->st_name, obj->path);
			}
			store_ptr(where, val, rlen);
			break;
		}

#ifdef __mips_n64
		case R_TYPE(TLS_DTPMOD64):
#else
		case R_TYPE(TLS_DTPMOD32): 
#endif
		{

			const size_t rlen = sizeof(Elf_Addr);
			Elf_Addr old = load_ptr(where, rlen);
			Elf_Addr val = old;

        		def = find_symdef(r_symndx, obj, &defobj, flags, NULL,
	    			lockstate);
			if (def == NULL)
				return -1;

			val += (Elf_Addr)defobj->tlsindex;

			store_ptr(where, val, rlen);
			dbg("DTPMOD %s in %s %p --> %p in %s",
			    obj->strtab + obj->symtab[r_symndx].st_name,
			    obj->path, (void *)old, (void*)val, defobj->path);
			break;
		}

#ifdef __mips_n64
		case R_TYPE(TLS_DTPREL64):
#else
		case R_TYPE(TLS_DTPREL32):
#endif
		{
			const size_t rlen = sizeof(Elf_Addr);
			Elf_Addr old = load_ptr(where, rlen);
			Elf_Addr val = old;

        		def = find_symdef(r_symndx, obj, &defobj, flags, NULL,
	    			lockstate);
			if (def == NULL)
				return -1;

			if (!defobj->tls_done && allocate_tls_offset(obj))
				return -1;

			val += (Elf_Addr)def->st_value - TLS_DTP_OFFSET;
			store_ptr(where, val, rlen);

			dbg("DTPREL %s in %s %p --> %p in %s",
			    obj->strtab + obj->symtab[r_symndx].st_name,
			    obj->path, (void*)old, (void *)val, defobj->path);
			break;
		}

#ifdef __mips_n64
		case R_TYPE(TLS_TPREL64):
#else
		case R_TYPE(TLS_TPREL32):
#endif
		{
			const size_t rlen = sizeof(Elf_Addr);
			Elf_Addr old = load_ptr(where, rlen);
			Elf_Addr val = old;

        		def = find_symdef(r_symndx, obj, &defobj, flags, NULL,
	    			lockstate);

			if (def == NULL)
				return -1;

			if (!defobj->tls_done && allocate_tls_offset(obj))
				return -1;

			val += (Elf_Addr)(def->st_value + defobj->tlsoffset
			    - TLS_TP_OFFSET - TLS_TCB_SIZE);
			store_ptr(where, val, rlen);

			dbg("TPREL %s in %s %p --> %p in %s",
			    obj->strtab + obj->symtab[r_symndx].st_name,
			    obj->path, (void*)old, (void *)val, defobj->path);
			break;
		}



		default:
			dbg("sym = %lu, type = %lu, offset = %p, "
			    "contents = %p, symbol = %s",
			    (u_long)r_symndx, (u_long)ELF_R_TYPE(rel->r_info),
			    (void *)rel->r_offset,
			    (void *)load_ptr(where, sizeof(Elf_Sword)),
			    obj->strtab + obj->symtab[r_symndx].st_name);
			_rtld_error("%s: Unsupported relocation type %ld "
			    "in non-PLT relocations",
			    obj->path, (u_long) ELF_R_TYPE(rel->r_info));
			return -1;
		}
	}

	return 0;
}
Example #16
0
void _System::FullGC(Interpreter*, VMFrame* frame) {
    frame->Pop();
    GetHeap<HEAP_CLS>()->triggerGC(); // not safe to do it immediatly, will be done when it is ok, i.e., in the interpreter loop
    frame->Push(load_ptr(trueObject));
}
Example #17
0
long VMMethod::GetNumberOfBytecodes() const {
    return INT_VAL(load_ptr(bcLength));
}
Example #18
0
long VMMethod::GetMaximumNumberOfStackElements() const {
    return INT_VAL(load_ptr(maximumNumberOfStackElements));
}
Example #19
0
static int
reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
    RtldLockState *lockstate)
{
	Elf_Addr        *where;
	const Elf_Sym   *def;
	const Obj_Entry *defobj;
	Elf_Addr         tmp;
	unsigned long	 symnum;

	where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
	symnum = ELF_R_SYM(rel->r_info);

	switch (ELF_R_TYPE(rel->r_info)) {
	case R_ARM_NONE:
		break;
		
#if 1 /* XXX should not occur */
	case R_ARM_PC24: {	/* word32 S - P + A */
		Elf32_Sword addend;
		
		/*
		 * Extract addend and sign-extend if needed.
		 */
		addend = *where;
		if (addend & 0x00800000)
			addend |= 0xff000000;
		
		def = find_symdef(symnum, obj, &defobj, false, cache,
		    lockstate);
		if (def == NULL)
				return -1;
			tmp = (Elf_Addr)obj->relocbase + def->st_value
			    - (Elf_Addr)where + (addend << 2);
			if ((tmp & 0xfe000000) != 0xfe000000 &&
			    (tmp & 0xfe000000) != 0) {
				_rtld_error(
				"%s: R_ARM_PC24 relocation @ %p to %s failed "
				"(displacement %ld (%#lx) out of range)",
				    obj->path, where,
				    obj->strtab + obj->symtab[symnum].st_name,
				    (long) tmp, (long) tmp);
				return -1;
			}
			tmp >>= 2;
			*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
			dbg("PC24 %s in %s --> %p @ %p in %s",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)*where, where, defobj->path);
			break;
		}
#endif

		case R_ARM_ABS32:	/* word32 B + S + A */
		case R_ARM_GLOB_DAT:	/* word32 B + S */
			def = find_symdef(symnum, obj, &defobj, false, cache,
			    lockstate);
			if (def == NULL)
				return -1;
			if (__predict_true(RELOC_ALIGNED_P(where))) {
				tmp =  *where + (Elf_Addr)defobj->relocbase +
				    def->st_value;
				*where = tmp;
			} else {
				tmp = load_ptr(where) +
				    (Elf_Addr)defobj->relocbase +
				    def->st_value;
				store_ptr(where, tmp);
			}
			dbg("ABS32/GLOB_DAT %s in %s --> %p @ %p in %s",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)tmp, where, defobj->path);
			break;

		case R_ARM_RELATIVE:	/* word32 B + A */
			if (__predict_true(RELOC_ALIGNED_P(where))) {
				tmp = *where + (Elf_Addr)obj->relocbase;
				*where = tmp;
			} else {
				tmp = load_ptr(where) +
				    (Elf_Addr)obj->relocbase;
				store_ptr(where, tmp);
			}
			dbg("RELATIVE in %s --> %p", obj->path,
			    (void *)tmp);
			break;

		case R_ARM_COPY:
			/*
			 * These are deferred until all other relocations have
			 * been done.  All we do here is make sure that the
			 * COPY relocation is not in a shared library.  They
			 * are allowed only in executable files.
			 */
			if (!obj->mainprog) {
				_rtld_error(
			"%s: Unexpected R_COPY relocation in shared library",
				    obj->path);
				return -1;
			}
			dbg("COPY (avoid in main)");
			break;

		default:
			dbg("sym = %lu, type = %lu, offset = %p, "
			    "contents = %p, symbol = %s",
			    symnum, (u_long)ELF_R_TYPE(rel->r_info),
			    (void *)rel->r_offset, (void *)load_ptr(where),
			    obj->strtab + obj->symtab[symnum].st_name);
			_rtld_error("%s: Unsupported relocation type %ld "
			    "in non-PLT relocations\n",
			    obj->path, (u_long) ELF_R_TYPE(rel->r_info));
			return -1;
	}
	return 0;
}
Example #20
0
StdString VMBlock::AsDebugString() const {
    return "Block(" + load_ptr(blockMethod)->AsDebugString() + ")";
}
Example #21
0
VMClass* Universe::GetBlockClass() const {
    return load_ptr(blockClass);
}
Example #22
0
VMMethod* VMBlock::GetMethod() const {
    return load_ptr(blockMethod);
}
Example #23
0
VMSymbol* Universe::SymbolFor(const StdString& str) {
    map<string,GCSymbol*>::iterator it = symbolsMap.find(str);
    return (it == symbolsMap.end()) ? NewSymbol(str) : load_ptr(it->second);
}
Example #24
0
void Interpreter::doJumpIfTrue(long bytecodeIndex) {
    vm_oop_t value = GetFrame()->Pop();
    if (value == load_ptr(trueObject))
        doJump(bytecodeIndex);
}
Example #25
0
void Universe::initialize(long _argc, char** _argv) {
#ifdef GENERATE_ALLOCATION_STATISTICS
    allocationStats["VMArray"] = {0,0};
#endif

    heapSize = 1 * 1024 * 1024;

    vector<StdString> argv = handleArguments(_argc, _argv);
    
    // remember file that was executed (for writing statistics)
    if (argv.size() > 0)
        bm_name = argv[0];

    Heap<HEAP_CLS>::InitializeHeap(heapSize);

    interpreter = new Interpreter();

#if CACHE_INTEGER
# warning is _store_ptr sufficient/correct here?
    // create prebuilt integers
    for (long it = INT_CACHE_MIN_VALUE; it <= INT_CACHE_MAX_VALUE; ++it) {
        prebuildInts[(unsigned long)(it - INT_CACHE_MIN_VALUE)] = _store_ptr(new (GetHeap<HEAP_CLS>()) VMInteger(it));
    }
#endif

    InitializeGlobals();

    VMObject* systemObject = NewInstance(load_ptr(systemClass));

    SetGlobal(SymbolForChars("nil"),    load_ptr(nilObject));
    SetGlobal(SymbolForChars("true"),   load_ptr(trueObject));
    SetGlobal(SymbolForChars("false"),  load_ptr(falseObject));
    SetGlobal(SymbolForChars("system"), systemObject);
    SetGlobal(SymbolForChars("System"), load_ptr(systemClass));
    SetGlobal(SymbolForChars("Block"),  load_ptr(blockClass));

    symbolIfTrue  = _store_ptr(SymbolForChars("ifTrue:"));
    symbolIfFalse = _store_ptr(SymbolForChars("ifFalse:"));

    

    VMMethod* bootstrapMethod = NewMethod(SymbolForChars("bootstrap"), 1, 0);
    bootstrapMethod->SetBytecode(0, BC_HALT);
    bootstrapMethod->SetNumberOfLocals(0);

    bootstrapMethod->SetMaximumNumberOfStackElements(2);
    bootstrapMethod->SetHolder(load_ptr(systemClass));

    if (argv.size() == 0) {
        Shell* shell = new Shell(bootstrapMethod);
        shell->Start();
        return;
    }

    /* only trace bootstrap if the number of cmd-line "-d"s is > 2 */
    short trace = 2 - dumpBytecodes;
    if (!(trace > 0))
        dumpBytecodes = 1;

    VMArray* argumentsArray = NewArrayFromStrings(argv);

    VMFrame* bootstrapFrame = interpreter->PushNewFrame(bootstrapMethod);
    bootstrapFrame->Push(systemObject);
    bootstrapFrame->Push(argumentsArray);

    VMInvokable* initialize = load_ptr(systemClass)->LookupInvokable(
                                            SymbolForChars("initialize:"));
    (*initialize)(bootstrapFrame);

    // reset "-d" indicator
    if (!(trace > 0))
        dumpBytecodes = 2 - trace;

    interpreter->Start();
}
Example #26
0
void Universe::InitializeGlobals() {
    set_vt_to_null();
    
# warning is _store_ptr sufficient?
    
    //
    //allocate nil object
    //
    VMObject* nil = new (GetHeap<HEAP_CLS>()) VMObject;
    nilObject = _store_ptr(nil);
    nil->SetClass((VMClass*) nil);

    metaClassClass = _store_ptr(NewMetaclassClass());

    objectClass     = _store_ptr(NewSystemClass());
    nilClass        = _store_ptr(NewSystemClass());
    classClass      = _store_ptr(NewSystemClass());
    arrayClass      = _store_ptr(NewSystemClass());
    symbolClass     = _store_ptr(NewSystemClass());
    methodClass     = _store_ptr(NewSystemClass());
    integerClass    = _store_ptr(NewSystemClass());
    primitiveClass  = _store_ptr(NewSystemClass());
    stringClass     = _store_ptr(NewSystemClass());
    doubleClass     = _store_ptr(NewSystemClass());

    nil->SetClass(load_ptr(nilClass));

    InitializeSystemClass(load_ptr(objectClass),                  nullptr, "Object");
    InitializeSystemClass(load_ptr(classClass),     load_ptr(objectClass), "Class");
    InitializeSystemClass(load_ptr(metaClassClass),  load_ptr(classClass), "Metaclass");
    InitializeSystemClass(load_ptr(nilClass),       load_ptr(objectClass), "Nil");
    InitializeSystemClass(load_ptr(arrayClass),     load_ptr(objectClass), "Array");
    InitializeSystemClass(load_ptr(methodClass),     load_ptr(arrayClass), "Method");
    InitializeSystemClass(load_ptr(stringClass),    load_ptr(objectClass), "String");
    InitializeSystemClass(load_ptr(symbolClass),    load_ptr(stringClass), "Symbol");
    InitializeSystemClass(load_ptr(integerClass),   load_ptr(objectClass), "Integer");
    InitializeSystemClass(load_ptr(primitiveClass), load_ptr(objectClass), "Primitive");
    InitializeSystemClass(load_ptr(doubleClass),    load_ptr(objectClass), "Double");

    // Fix up objectClass
    load_ptr(objectClass)->SetSuperClass((VMClass*) nil);

    obtain_vtables_of_known_classes(nil->GetClass()->GetName());
    
#if USE_TAGGING
    GlobalBox::updateIntegerBox(NewInteger(1));
#endif

    LoadSystemClass(load_ptr(objectClass));
    LoadSystemClass(load_ptr(classClass));
    LoadSystemClass(load_ptr(metaClassClass));
    LoadSystemClass(load_ptr(nilClass));
    LoadSystemClass(load_ptr(arrayClass));
    LoadSystemClass(load_ptr(methodClass));
    LoadSystemClass(load_ptr(symbolClass));
    LoadSystemClass(load_ptr(integerClass));
    LoadSystemClass(load_ptr(primitiveClass));
    LoadSystemClass(load_ptr(stringClass));
    LoadSystemClass(load_ptr(doubleClass));

    blockClass = _store_ptr(LoadClass(SymbolForChars("Block")));

    VMSymbol* trueClassName = SymbolForChars("True");
    trueClass  = _store_ptr(LoadClass(trueClassName));
    trueObject = _store_ptr(NewInstance(load_ptr(trueClass)));
    
    VMSymbol* falseClassName = SymbolForChars("False");
    falseClass  = _store_ptr(LoadClass(falseClassName));
    falseObject = _store_ptr(NewInstance(load_ptr(falseClass)));

    systemClass = _store_ptr(LoadClass(SymbolForChars("System")));
}
Example #27
0
void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
	const Elf_Rel *rel = 0, *rellim;
	Elf_Addr relsz = 0;
	const Elf_Sym *symtab = NULL, *sym;
	Elf_Addr *where;
	Elf_Addr *got = NULL;
	Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0;
	size_t i;

	for (; dynp->d_tag != DT_NULL; dynp++) {
		switch (dynp->d_tag) {
		case DT_REL:
			rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_RELSZ:
			relsz = dynp->d_un.d_val;
			break;
		case DT_SYMTAB:
			symtab = (const Elf_Sym *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_PLTGOT:
			got = (Elf_Addr *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_MIPS_LOCAL_GOTNO:
			local_gotno = dynp->d_un.d_val;
			break;
		case DT_MIPS_SYMTABNO:
			symtabno = dynp->d_un.d_val;
			break;
		case DT_MIPS_GOTSYM:
			gotsym = dynp->d_un.d_val;
			break;
		}
	}

	i = (got[1] & GOT1_MASK) ? 2 : 1;
	/* Relocate the local GOT entries */
	got += i;
	for (; i < local_gotno; i++) {
		*got++ += relocbase;
	}

	sym = symtab + gotsym;
	/* Now do the global GOT entries */
	for (i = gotsym; i < symtabno; i++) {
		*got = sym->st_value + relocbase;
		++sym;
		++got;
	}

	rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
	for (; rel < rellim; rel++) {
		Elf_Word r_symndx, r_type;

		where = (void *)(relocbase + rel->r_offset);

		r_symndx = ELF_R_SYM(rel->r_info);
		r_type = ELF_R_TYPE(rel->r_info);

		switch (r_type & 0xff) {
		case R_TYPE(REL32): {
			const size_t rlen =
			    ELF_R_NXTTYPE_64_P(r_type)
				? sizeof(Elf_Sxword)
				: sizeof(Elf_Sword);
			Elf_Sxword old = load_ptr(where, rlen);
			Elf_Sxword val = old;
#ifdef __mips_n64
			assert(r_type == R_TYPE(REL32)
			    || r_type == (R_TYPE(REL32)|(R_TYPE(64) << 8)));
#endif
			assert(r_symndx < gotsym);
			sym = symtab + r_symndx;
			assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL);
			val += relocbase;
			store_ptr(where, val, sizeof(Elf_Sword));
			dbg("REL32/L(%p) %p -> %p in <self>",
			    where, (void *)old, (void *)val);
			store_ptr(where, val, rlen);
			break;
		}

		case R_TYPE(GPREL32):
		case R_TYPE(NONE):
			break;


		default:
			abort();
			break;
		}
	}
}
Example #28
0
VMSymbol* VMInvokable::GetSignature() const {
    return load_ptr(signature);
}
Example #29
0
/* Process one elf relocation with addend. */
static int
elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
    int type, int local, elf_lookup_fn lookup)
{
	Elf_Addr *where;
	Elf_Addr addr;
	Elf_Addr addend;
	Elf_Word rtype, symidx;
	const Elf_Rel *rel;
	const Elf_Rela *rela;
	int error;

	switch (type) {
	case ELF_RELOC_REL:
		rel = (const Elf_Rel *)data;
		where = (Elf_Addr *) (relocbase + rel->r_offset);
		addend = load_ptr(where);
		rtype = ELF_R_TYPE(rel->r_info);
		symidx = ELF_R_SYM(rel->r_info);
		break;
	case ELF_RELOC_RELA:
		rela = (const Elf_Rela *)data;
		where = (Elf_Addr *) (relocbase + rela->r_offset);
		addend = rela->r_addend;
		rtype = ELF_R_TYPE(rela->r_info);
		symidx = ELF_R_SYM(rela->r_info);
		break;
	default:
		panic("unknown reloc type %d\n", type);
	}

	if (local) {
		if (rtype == R_ARM_RELATIVE) {	/* A + B */
			addr = elf_relocaddr(lf, relocbase + addend);
			if (load_ptr(where) != addr)
				store_ptr(where, addr);
		}
		return (0);
	}

	switch (rtype) {

		case R_ARM_NONE:	/* none */
			break;

		case R_ARM_ABS32:
			error = lookup(lf, symidx, 1, &addr);
			if (error != 0)
				return -1;
			store_ptr(where, addr + load_ptr(where));
			break;

		case R_ARM_COPY:	/* none */
			/*
			 * There shouldn't be copy relocations in kernel
			 * objects.
			 */
			printf("kldload: unexpected R_COPY relocation\n");
			return -1;
			break;

		case R_ARM_JUMP_SLOT:
			error = lookup(lf, symidx, 1, &addr);
			if (error == 0) {
				store_ptr(where, addr);
				return (0);
			}
			return (-1);
		case R_ARM_RELATIVE:
			break;

		default:
			printf("kldload: unexpected relocation type %d\n",
			       rtype);
			return -1;
	}
	return(0);
}
Example #30
0
VMClass* VMInvokable::GetHolder() const {
    return load_ptr(holder);
}