diff --git a/library/cpu/generic/bcopy.S b/library/cpu/generic/bcopy.S index 98f215c2..c427ffd9 100644 --- a/library/cpu/generic/bcopy.S +++ b/library/cpu/generic/bcopy.S @@ -66,7 +66,7 @@ // Main entry points. -.align 5 + .align 5 .global bcopy_g3 bcopy_g3: // void bcopy(const void *src, void *dst, size_t len) diff --git a/library/profile/gmon.c b/library/profile/gmon.c index b5f115e7..5a3219b9 100644 --- a/library/profile/gmon.c +++ b/library/profile/gmon.c @@ -175,7 +175,7 @@ void moncleanup(void) { if (p->froms[fromindex] == 0) continue; - frompc = 0; /* FIXME: was p->lowpc; needs to be 0 and assumes -Ttext=0 on compile. Better idea? */ + frompc = p->lowpc; //0x01000000; /* FIXME: was p->lowpc; needs to be 0 and assumes -Ttext=0 on compile. Better idea? */ frompc += fromindex * p->hashfraction * sizeof(*p->froms); for (toindex = p->froms[fromindex]; toindex != 0; toindex = p->tos[toindex].link) { @@ -213,41 +213,41 @@ void mongetpcs(uint32 *lowpc, uint32 *highpc) { *highpc = 0; ElfBase = OpenLibrary("elf.library", 0L); - if (!ElfBase) - goto out; - - IElf = (struct ElfIFace *) GetInterface(ElfBase, "main", 1, NULL); - if (!IElf) - goto out; - - self = (struct Process *) FindTask(0); - seglist = GetProcSegList(self, GPSLF_CLI | GPSLF_SEG); - - GetSegListInfoTags(seglist, GSLI_ElfHandle, &elfHandle, TAG_DONE); - elfHandle = OpenElfTags(OET_ElfHandle, elfHandle, TAG_DONE); - - if (!elfHandle) - goto out; - - GetElfAttrsTags(elfHandle, EAT_NumSections, &numSections, TAG_DONE); - - for (i = 0; i < numSections; i++) { - shdr = GetSectionHeaderTags(elfHandle, GST_SectionIndex, i, TAG_DONE); - if (shdr && (shdr->sh_flags & SWF_EXECINSTR)) { - uint32 base = (uint32) GetSectionTags(elfHandle, GST_SectionIndex, i, TAG_DONE); - *lowpc = base; - *highpc = base + shdr->sh_size; - break; + if (ElfBase) { + IElf = (struct ElfIFace *) GetInterface(ElfBase, "main", 1, NULL); + if (IElf) { + self = (struct Process *) FindTask(0); + seglist = GetProcSegList(self, GPSLF_CLI | GPSLF_SEG); + + if (GetSegListInfoTags(seglist, GSLI_ElfHandle, &elfHandle, TAG_DONE) == 1) { + elfHandle = OpenElfTags(OET_ElfHandle, elfHandle, TAG_DONE); + + if (elfHandle) { + GetElfAttrsTags(elfHandle, EAT_NumSections, &numSections, TAG_DONE); + for (i = 0; i < numSections; i++) { + shdr = GetSectionHeaderTags(elfHandle, GST_SectionIndex, i, TAG_DONE); + if (shdr && (shdr->sh_flags & SWF_EXECINSTR)) { + uint32 base = (uint32) GetSectionTags(elfHandle, GST_SectionIndex, i, TAG_DONE); + *lowpc = base; + *highpc = base + shdr->sh_size; + break; + } + } + + CloseElfTags(elfHandle, CET_ReClose, TRUE, TAG_DONE); + } + } } } - CloseElfTags(elfHandle, CET_ReClose, TRUE, TAG_DONE); - -out: - if (IElf) + if (IElf) { DropInterface((struct Interface *) IElf); - if (ElfBase) + IElf = NULL; + } + if (ElfBase) { CloseLibrary(ElfBase); + ElfBase = NULL; + } } #include "macros.h" diff --git a/library/profile/mcount.S b/library/profile/mcount.S index e35f961d..90f2c647 100644 --- a/library/profile/mcount.S +++ b/library/profile/mcount.S @@ -1,40 +1,89 @@ // -// $Id: profile_mcount.S,v 1.0 2021-01-18 12:04:26 clib2devs Exp $ +// $Id: profile_mcount.S,v 1.1 2023-08-25 12:04:26 clib2devs Exp $ // +/* PowerPC-specific implementation of profiling support. + Copyright (C) 1997, 1999, 2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. - .globl _mcount - .type _mcount,@function -_mcount: - stwu r1,-64(r1) - stw r3,16(r1) - stw r4,20(r1) - stw r5,24(r1) - stw r6,28(r1) - stw r7,32(r1) - stw r8,36(r1) - stw r9,40(r1) - stw r10,44(r1) + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ + +/* We do profiling as described in the SYSV ELF ABI, except that glibc + _mcount manages its own counters. The caller has put the address the + caller will return to in the usual place on the stack, 4(r1). _mcount + is responsible for ensuring that when it returns no argument-passing + registers are disturbed, and that the LR is set back to (what the + caller sees as) 4(r1). + This is intended so that the following code can be inserted at the + front of any routine without changing the routine: + + .data + mflr r0 + stw r0,4(r1) + bl _mcount +*/ + +#ifdef PIC +# define JUMPTARGET(name) name##@plt +#else +# define JUMPTARGET(name) name +#endif + + .text + .align 2 + .global _mcount + .type _mcount, @function +_mcount: + .cfi_startproc + stwu r1,-48(r1) + .cfi_adjust_cfa_offset 48 +/* We need to save the parameter-passing registers. */ + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) mflr r4 - stw r4,48(r1) - lwz r3,68(r1) - - bl __mcount - lwz r3,68(r1) - mtlr r3 - lwz r4,48(r1) - mtctr r4 - - lwz r3,16(r1) - lwz r4,20(r1) - lwz r5,24(r1) - lwz r6,28(r1) - lwz r7,32(r1) - lwz r8,36(r1) - lwz r9,40(r1) - lwz r10,44(r1) - addi r1,r1,64 + lwz r3, 52(r1) + mfcr r5 + stw r7, 28(r1) + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + stw r4, 44(r1) + .cfi_offset lr, -4 + stw r5, 8(r1) + bl JUMPTARGET(__mcount) + /* Restore the registers... */ + lwz r6, 8(r1) + lwz r0, 44(r1) + lwz r3, 12(r1) + mtctr r0 + lwz r4, 16(r1) + mtcrf 0xff,r6 + lwz r5, 20(r1) + lwz r6, 24(r1) + lwz r0, 52(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + mtlr r0 + lwz r9, 36(r1) + lwz r10,40(r1) + /* ...unwind the stack frame, and return to your usual programming. */ + addi r1,r1,48 bctr -_mcount_end: - .size _mcount,_mcount_end-_mcount + .cfi_endproc + .size _mcount,.-_mcount