首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏函数式编程语言及工具

    Scalaz(35)- Free :运算-Trampoline,say NO to StackOverflowError

    我们提到过用Trampoline可以heap换stack,以遍历数据结构代替递归运算来实现运行安全。那么什么是Trampoline呢? 1 sealed trait Trampoline[+A] 2 case class Done[A](a: A) extends Trampoline[A] 3 case class More[A]( k: () => Trampoline[A]) extends Trampoline[A] Trampoline就是一种数据结构。 它有两种状态:Done(a: A)代表结构内存放了一个A值,More(k: ()=>Trampoline[A])代表结构内存放的是一个Function0函数,就是一个运算Trampoline[A]。 我们可以把scalaz的Trampoline用在even,odd函数里: 1 import scalaz.Free.Trampoline 2 def even(xa: List[Int]): Trampoline

    91791发布于 2018-01-05
  • 来自专栏函数式编程语言及工具

    泛函编程(29)-泛函实用结构:Trampoline-不再怕StackOverflow

    [A] 8 case class More[+A](k: () => Trampoline[A]) extends Trampoline[A] Trampoline代表一个可以一步步进行的运算。 有了Trampoline我们可以把even,odd的函数类型换成Trampoline: 1 def even[A](as: List[A]): Trampoline[Boolean] = as match FlatMap[A,B](sub: Trampoline[A], k: A => Trampoline[B]) extends Trampoline[B] case class FlatMap这种Trampoline : Trampoline[A], k: A => Trampoline[B]) extends Trampoline[B] 在以上对Trampoline的调整里我们引用了Monad的结合特性(associativity : Trampoline[A], k: A => Trampoline[B]) extends Trampoline[B] 我们可以用这个zip函数把几个Trampoline运算交叉组合起来实现并行运算

    2K101发布于 2018-01-05
  • 来自专栏软件设计

    6.S081/6.828: xv6源码分析--trap机制

    跳转到STVEC指向的代码,也就是trampoline page中,这个是从supervisor mode返回user mode时设置的。 图片3 trampoline.uservec之前讲解过用户页表的布局,虚拟地址最高处的几页比较特殊,trampoline是trap代码,系统调用进入内核的必经之路,此时会执行trampoline.S中uservec 代码进行保存用户寄存器到trapframe,并将trapframe中的内核参数设置到指定寄存器,trampoline这一页每个进程都有,共享同一个物理页,但是trampoline这一页没有PTE_U,不能被用户态执行 intr_off(); // send syscalls, interrupts, and exceptions to trampoline.S w_stvec(TRAMPOLINE + (uservec uint64 fn = TRAMPOLINE + (userret - trampoline);//执行trampoline.userret代码段,这两个参数分别放到a0、a1寄存器中 ((void

    1.5K52编辑于 2022-11-26
  • 来自专栏软件设计

    6.S081/6.828: xv6源码分析--页表

    trampoline在内核页表、用户页表都有,是用于用户态和内核态切换的,涉及到页表地址的设置。 kvmmap(kpgtbl, TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X); // map kernel stacks proc_mapstacks trampolinetrampoline.S文件的字符数组映射到虚拟地址最高端用于内陷。 //用户页表最高处是trampoline,用于中断,不属于用户 if(mappages(pagetable, TRAMPOLINE, PGSIZE, (uint64)trampoline , for trampoline.S.

    1.4K40编辑于 2022-11-26
  • 来自专栏函数式编程语言及工具

    泛函编程(30)-泛函IO:Free Monad-Monad生产线

        在上节我们介绍了Trampoline。它主要是为了解决堆栈溢出(StackOverflow)错误而设计的。 Trampoline类型是一种数据结构,它的设计思路是以heap换stack:对应传统递归算法运行时在堆栈上寄存程序状态,用Trampoline进行递归算法时程序状态是保存在Trampoline的数据结构里的 所以IO算法设计也会采用与Trampoline一样的数据结构。或者我们应该沿用Trampoline数据结构和算法来设计IO组件库。如此思考那么我们就必须对Trampoline进行深度抽象了。 ,<function1>) 7 8 prg.foldMap(TestConsole) 在上一节我们讨论了Trampoline。主要目的是解决泛函算法中不可避免的堆栈溢出问题。 我们应该考虑在Free Monad里使用Trampoline类型。这样我们才可以放心地用Free Monad来产生任何类型的Monad并在运算中以heap换stack解决堆栈溢出问题。

    1.6K70发布于 2018-01-05
  • 来自专栏kayden

    自动化攻击取证

    struct.pack("<L", page[0] + offset) tramp += "\xff\xe3" if trampoline_offset ] <= equals_button and equals_button < (page[0] + page[1] -7): print "[*] Found our trampoline = physical+ v_offset print "[*] Found our trampoline target at: 0x%08x" % (trampoline_offset if slack_space is not None: break print "[*] Writing trampoline fd = open(memory_file, "r+") fd.seek(trampoline_offset) fd.write(tramp) fd.close

    92810编辑于 2022-09-29
  • 来自专栏c++与qt学习

    MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 --Trap -- 中

    fn函数是就是刚刚我向你展示的位于trampoline.S中的代码。 程序现在仍然在trampoline的最开始,也就是uservec函数的最开始,我们基本上还没有执行任何内容。 因为我们还在trampoline代码中,而trampoline代码在用户空间和内核空间都映射到了同一个地址。 在下一行我们设置了STVEC寄存器指向trampoline代码,在那里最终会执行sret指令返回到用户空间。位于trampoline代码最后的sret指令会重新打开中断。 为什么trampoline代码中不保存SEPC寄存器? trampoline代码没有像其他寄存器一样保存这个寄存器,但是非常欢迎大家修改XV6来保存它。 实际上,我们会在汇编代码trampoline中完成page table的切换,并且也只能在trampoline中完成切换,因为只有trampoline中代码是同时在用户和内核空间中映射。

    95941编辑于 2023-10-11
  • 来自专栏函数式编程语言及工具

    泛函编程(31)-泛函IO:Free Monad-Running free

    前面我们介绍了Trampoline的运算模式可以有效解决堆栈溢出问题,而上节的Free Monad介绍里还没有把Free Monad与Trampoline运算模式挂上钩。 我们先考虑一下如何在Free Monad数据类型里引入Trampoline运算模式。 [A] { 14 private case class FlatMap[B](a: Trampoline[A], f: A => Trampoline[B]) extends Trampoline[ [A] 38 case class More[A](k: () => Trampoline[A]) extends Trampoline[A] 这两个数据类型的设计目的都是为了能逐步运行算法:按照算法运算的状态确定下一步该如何运行 为了实现Free Monad在运行中采用Trampoline运行机制,我们可以像Trampoline数据类型一样来实现resume,这个确定每一步运算方式的函数: 1 trait Free[F[_],

    1.5K100发布于 2018-01-05
  • 来自专栏安全的矛与盾

    minHook源码阅读分析

    LPVOID pTrampoline; // Address of the trampoline function. LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function. } TRAMPOLINE, *PTRAMPOLINE = hs.len) return FALSE; // Trampoline function is too large. if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE) return FALSE; // Trampoline function

    1.2K20编辑于 2023-02-27
  • 来自专栏c++与qt学习

    MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 --Trap -- 上

    . // 为进程的用户态页表分配一个新的空闲物理页--同时做好TRAMPOLINETRAMPOLINE的映射 // TRAMPOLINETRAMPOLINE这两部分代码是上下文切换通用代码, usertrapret函数中会执行S态返回用户态的操作: //proc.c //这三个外部全局遍历定义在trampoline.s中 extern char trampoline[], uservec[ (TRAPFRAME, satp); } trampoline,uservec,userret是定义在trampoline.S中的三个全局符号,其中trampoline 符号是一个占位符标记,并不包含任何指令地址 xv6使用包含uservec的蹦床页面(trampoline page)来满足这些约束。xv6将蹦床页面映射到内核页表和每个用户页表中相同的虚拟地址。这个虚拟地址是TRAMPOLINE。 蹦床内容在trampoline.S中设置,并且(当执行用户代码时)stvec设置为uservec (kernel/trampoline.S:16)。

    1.1K21编辑于 2023-10-11
  • 来自专栏火丁笔记

    PHP与Recursion

    好在天无绝人之路,仔细阅读维基百科中关于尾调用的介绍,你会发现里面提到了Trampoline的概念。 function() use($n, $accumulator) { return factorial($n - 1, $accumulator * $n); }; } function trampoline while (is_callable($result)) { $result = $result(); } return $result; } var_dump(trampoline 除非能提升代码可读性,否则没有必要使用递归;迫不得已之时,最好考虑使用Tail Call或Trampoline等技术来规避潜在的栈溢出问题。

    1.3K20编辑于 2021-12-14
  • 来自专栏操作系统

    从底层源码剖析操作系统如何切换用户态与内核态

    sret的去向 scause:RISC-V在此处放置了一个数字来描述当前程序发生异常的原因等信息 sscratch:内核在这里放置了一个值,一般用于临时存储上一个程序的返回地址,方便程序最后跳转回原来程序 trampoline 将用户态原本要执行的下一条指令地址保存到sepc中,保证操作系统执行完内核态的代码后能够跳转回用户态继续执行 (3)跳转到stvec对应的地址执行内核处理程序 因此在执行完ecall后,当前便切换到了内核态中执行程序代码 Step2: Trampoline trampoline意为蹦床,字面理解就是来回蹦,实际上也确实是这样,当操作系统切换状态时,总会执行这段程序来完成状态的切换,这里我们可以从trampoline.S对应的源码来分析: 首先是这段代码: usertrapret()函数中,来完成跳转到用户态的操作 接下来在usertrapret()函数中,我们会将用户态对应的页表地址(satp)、栈针地址(sp)、编号(hartid)等信息恢复,之后通过计算trampoline 中的userret地址,再次返回到trampoline中,执行接下来的userret操作 在接下来trampoline的userret中,将原本的用户态首地址信息恢复,之后恢复用户态的寄存器信息,恢复用户态的返回

    1.3K30编辑于 2024-10-17
  • 来自专栏有价值炮灰

    Frida Internal - Part 3: Java Bridge 与 ART hook

    _; const void* quick_imt_conflict_trampoline_; const void* quick_generic_jni_trampoline_; // :Runtime 中获得了,因此可以用前面类似的搜索方法依次找出这几个 trampoline 的地址。 quick trampoline 一般是指被编译成 native 代码后的字节码在运行过程中所使用到的跳转地址表,比如 quick_resolution_trampoline_ 所指向的 stub 作用就是给 (native 代码)第一次调用某个方法时候解析指定方法,同理 generic_jni_trampoline 就是用来跳转到 JNI 方法(代码) 的 stub,quick_to_interpreter_bridge_trampoline 以 ARM64 为例,trampoline 的部分代码如下所示: Memory.patchCode(trampoline, 256, code => { const writer = new Arm64Writer

    2.4K20编辑于 2023-02-12
  • 来自专栏函数式编程语言及工具

    Scalaz(50)- scalaz-stream: 安全的无穷运算-running infinite stream freely

    EmitOrAwait[Nothing, O] case class Await[+F[_], A, +O]( req: F[A] , rcv: (EarlyCause \/ A) => Trampoline [Process[F, O]] @uncheckedVariance , preempt : A => Trampoline[Process[F,Nothing]] @uncheckedVariance = (_:A) => Trampoline.delay(halt:Process[F,Nothing]) ) extends HaltEmitOrAwait[F, O] with EmitOrAwait 值得注意的是不但Await和Append这两个状态转换方式是结构化的,它们的连接函数(continuation)运算结果也是包嵌在Trampoline里的。 Used in conjunction with `Step`. */ case class Cont[+F[_], +O](stack: Vector[Cause => Trampoline

    1.2K60发布于 2018-01-05
  • 来自专栏函数式编程语言及工具

    泛函编程(32)-泛函IO:IO Monad

    当然,我们前面讨论的Trampoline类型是最佳选择。 [A] { 14 def unit(a: A): Trampoline[A] = Done(a) 15 def flatMap[B](f: A => Trampoline[B]): Trampoline [A](k: () => Trampoline[A]) extends Trampoline[A] 它们有许多相似点。 我们可以把Trampoline类型的算法引进到IO类型中,这样就可以有效防止StackOverflow问题。 我们可以直接使用Free类型代表IO运算:用Free的Monadic编程语言来描述IO算法,用Interpreter来描述IO效果,用Free的Trampoline运算机制实现尾递归运算。

    2.9K70发布于 2018-01-05
  • 来自专栏乐百川的学习频道

    Groovy 闭包

    ) 文档原文是Trampoline,可惜我没明白是什么意思。 尾递归需要调用闭包的trampoline()方法,它会返回一个TrampolineClosure,具有尾递归特性。 注意这里我们需要将外层闭包和递归闭包都调用trampoline()方法,才能正确的使用尾递归特性。然后我们计算一个很大的数字,就不会出现爆栈错误了。 def factorial factorial = { int n, def accu = 1G -> if (n < 2) return accu factorial.trampoline (n - 1, n * accu) } factorial = factorial.trampoline() assert factorial(1) == 1 assert factorial(

    1.1K10编辑于 2022-05-05
  • 来自专栏CodeBuddy 系列文章

    蹦床弹跳:CodeBuddy 一句话生成的“弹跳乐园”

    height:30px;background-color:#FF5722;border-radius:50%;box-shadow:0010pxrgba(0,0,0,0.3);z-index:5;}.trampoline divclass="score-container">分数:<spanid="score">0

    <divclass="ball"id="ball">
    <divclass="<em>trampoline</em>"id ="<em>trampoline</em>">
    <divclass="game-over"id="game-over"><divclass="game-over-title">游戏结束
<divclass game-container');constball=document.getElementById('ball');consttrampoline=document.getElementById('trampoline &&ballY<trampoline.offsetTop+trampolineHeight&&ballX+ballSize>trampolineX&&ballX<trampolineX+trampolineWidth

38210编辑于 2025-09-02
  • 来自专栏函数式编程语言及工具

    Scalaz(44)- concurrency :scalaz Future,尚不完整的多线程类型

    object Future { case class Now[+A](a: A) extends Future[A] case class Async[+A](onFinish: (A => Trampoline : () => Future[A], f: A => Future[B]) extends Future[B] case class BindAsync[A,B](onFinish: (A => Trampoline fdelay,fapply分别把运算存入trampoline进行结构化了。 我们必须另外运算trampoline来运行结构内的运算: 1 fdelay.run //> run... 2 * exceptions. */ def async[A](listen: (A => Unit) => Unit): Future[A] = Async((cb: A => Trampoline

    95490发布于 2018-01-05
  • 来自专栏函数式编程语言及工具

    Scalaz(51)- scalaz-stream: 资源使用安全-Resource Safety

    ] >: F[x], O2 >: O](f: Cause => Process[F2, O2]): Process[F2, O2] = { val next = (t: Cause) => Trampoline.delay . */ final def asFinalizer: Process[F, O] = { def mkAwait[F[_], A, O](req: F[A], cln: A => Trampoline [Process[F,Nothing]])(rcv: EarlyCause \/ A => Trampoline[Process[F, O]]) = Await(req, rcv,cln) step } case Step(Await(req, rcv, cln), cont) => mkAwait(req, cln) { case -\/(Kill) => Trampoline.delay (Try(r.fold(Halt.apply, a => rcv(a) onComplete release(a) ))) }, { a: A => Trampoline.delay(release

    81170发布于 2018-01-05
  • 来自专栏Eureka的技术时光轴

    如何找SSDT中精准的

    xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0"; //mov rax, xxx ; jmp rax KIRQL Irql; ULONG SsdtEntry; PVOID trampoline ); // mov rax, @NewFunc; jmp rax *(PULONGLONG)(jmp_to_newFunction+2) = (ULONGLONG)hookedFunc; trampoline = SearchCodeCave(searchAddr); Dbg("trampoline : %llx\n", trampoline); mdl = IoAllocateMdl(trampoline NormalPagePriority); RtlMoveMemory(memAddr, jmp_to_newFunction, 12); SsdtEntry = GetSSDTEntry(KiServiceTable, trampoline

    1.5K20发布于 2019-07-24
  • 第 2 页第 3 页第 4 页第 5 页第 6 页第 7 页第 8 页第 9 页第 10 页第 11 页
    点击加载更多
    领券