Beispiel #1
0
func reorderGlobalConstructors(m llvm.Module) error {
	ctors := m.NamedGlobal("llvm.global_ctors")
	if ctors.IsNil() {
		// No global constructors.
		return nil
	}

	init := ctors.Initializer()
	arraylength := init.Type().ArrayLength()
	zeroindex := []uint32{0}

	// The constructors are ordered within each package, but the packages
	// are in reverse order. We must go backwards through the constructors,
	// reassigning priorities.
	ceiling, npackagectors := -1, -1
	for i := arraylength - 1; i >= 0; i-- {
		indices := []uint32{uint32(i)}
		ctor := llvm.ConstExtractValue(init, indices)
		priority := int(llvm.ConstExtractValue(ctor, zeroindex).ZExtValue())
		if npackagectors == -1 {
			ceiling = arraylength - (i + 1) + priority
			npackagectors = priority
		}
		newpriority := ceiling - (npackagectors - priority)
		newpriorityvalue := llvm.ConstInt(llvm.Int32Type(), uint64(newpriority), false)
		ctor = llvm.ConstInsertValue(ctor, newpriorityvalue, zeroindex)
		if priority == 1 {
			npackagectors = -1
		}
		init = llvm.ConstInsertValue(init, ctor, indices)
	}
	ctors.SetInitializer(init)
	return nil
}