aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/powerpc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-03-31 22:56:24 +0000
committerUlrich Drepper <drepper@redhat.com>1997-03-31 22:56:24 +0000
commit5929563ff20245bbaa1b3ca2f4bfcee623ac6fb5 (patch)
tree15b1ff0a40462018402078788148c0c99d188429 /sysdeps/powerpc
parent3075e0e37c0e7cc2e6eb518c409e0769d058ed4b (diff)
downloadglibc-5929563ff20245bbaa1b3ca2f4bfcee623ac6fb5.tar
glibc-5929563ff20245bbaa1b3ca2f4bfcee623ac6fb5.tar.gz
glibc-5929563ff20245bbaa1b3ca2f4bfcee623ac6fb5.tar.bz2
glibc-5929563ff20245bbaa1b3ca2f4bfcee623ac6fb5.zip
1997-04-01 00:37 Ulrich Drepper <drepper@cygnus.com> * math/Makefile: Prevent inlining for test-{float,double,longdouble}. * math/libm-test.c (initialize): Make strings unique and force values to memory. * posix/regex.c: Debug debugging code. * sysdeps/i386/asm-syntax.h: Define `L' macro to emit correct syntax for local label. * sysdeps/i386/add_n.S: Use correct local label syntax for the binary format. * sysdeps/i386/addmul_1.S: Likewise. * sysdeps/i386/lshift.S: Likewise. * sysdeps/i386/memchr.S: Likewise. * sysdeps/i386/memset.S: Likewise. * sysdeps/i386/mul_1.S: Likewise. * sysdeps/i386/rshift.S: Likewise. * sysdeps/i386/stpcpy.S: Likewise. * sysdeps/i386/stpncpy.S: Likewise. * sysdeps/i386/strchr.S: Likewise. * sysdeps/i386/strcspn.S: Likewise. * sysdeps/i386/strlen.S: Likewise. * sysdeps/i386/strpbrk.S: Likewise. * sysdeps/i386/strrchr.S: Likewise. * sysdeps/i386/strspn.S: Likewise. * sysdeps/i386/strtok.S: Likewise. * sysdeps/i386/sub_n.S: Likewise. * sysdeps/i386/submul_1.S: Likewise. * sysdeps/i386/i486/strcat.S: Likewise. * sysdeps/i386/i486/strlen.S: Likewise. * sysdeps/i386/i586/add_n.S: Likewise. * sysdeps/i386/i586/addmul_1.S: Likewise. * sysdeps/i386/i586/lshift.S: Likewise. * sysdeps/i386/i586/memset.S: Likewise. * sysdeps/i386/i586/mul_1.S: Likewise. * sysdeps/i386/i586/rshift.S: Likewise. * sysdeps/i386/i586/strchr.S: Likewise. * sysdeps/i386/i586/strlen.S: Likewise. * sysdeps/i386/i586/sub_n.S: Likewise. * sysdeps/i386/i586/submul_1.S: Likewise. * sysdeps/stub/s_log2l.c: Correct function name. * time/africa: Updated from ADO tzdata1997e. * time/aantarctica: Likewise. * time/asia: Likewise. * time/australia: Likewise. * time/europe: Likewise. * time/northamerica: Likewise. * time/southamerica: Likewise. * time/private.h: Updated from ADO tzcode1997d. * time/scheck.c: Likewise. 1997-03-31 12:42 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/powerpc/Dist: Add kernel_*.h files. 1997-03-23 01:41 Geoff Keating <geoffk@ozemail.com.au> * sysdeps/powerpc/strlen.s: Rewrote for more speed. * string/tst-strlen.c: Also test various string alignments. 1997-03-19 06:11 Geoff Keating <geoffk@ozemail.com.au> * sysdeps/unix/sysv/linux/powerpc/statbuf.h: Removed. * sysdeps/unix/sysv/linux/powerpc/kernel_stat.h: Added. * sysdeps/powerpc/dl-machine.h (ELF_PREFERRED_ADDRESS): Assume program base address is 0x01800000 if we can't otherwise tell what it is. (elf_machine_rela): Replace `assertion failed' with real error messages. * sysdeps/powerpc/dl-machine.h: More comments, more GNU indenting. Put in extra parentheses to make explicit the relative precedence of + and >>. * sysdeps/powerpc/bsd-setjmp.S: Add `__setjmp' symbol so the tests pass. * sysdeps/powerpc/clone.S: Rewrite. Probably still doesn't work. * sysdeps/unix/sysv/linux/powerpc/sys/sysdep.h: Use .section "text" instead of .text. 1997-03-31 02:28 Ulrich Drepper <drepper@cygnus.com> * misc/tst-tsearch.c: Don't write to stderr, write to stdout instead. * inet/inet_ntoa.c (inet_ntoa): Complete rewrite. Now uses thread-specific memory in multi-threaded programs. * sysdeps/stub/s_exp2.c: New file. Stub version for exp2 function. * sysdeps/stub/s_exp2f.c: New file. * sysdeps/stub/s_exp2l.c: New file. Reported by a sun <asun@zoology.washington.edu>. * sysdeps/unix/sysv/linux/netatalk/atalk.h: Rename to... * sysdeps/unix/sysv/linux/netatalk/at.h: ...this. Suggested by a sun <asun@zoology.washington.edu>. 1997-03-30 14:53 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/netinet/ip_icmp.h: Add former contents of <netinet/icmp.h>. Patch by a sun <asun@zoology.washington.edu>. * sysdeps/powerpc/strlen.S: Added.
Diffstat (limited to 'sysdeps/powerpc')
-rw-r--r--sysdeps/powerpc/bsd-setjmp.S7
-rw-r--r--sysdeps/powerpc/dl-machine.h201
-rw-r--r--sysdeps/powerpc/elf/start.c1
-rw-r--r--sysdeps/powerpc/strlen.S52
4 files changed, 142 insertions, 119 deletions
diff --git a/sysdeps/powerpc/bsd-setjmp.S b/sysdeps/powerpc/bsd-setjmp.S
index 19c2fe308c..1a6300660e 100644
--- a/sysdeps/powerpc/bsd-setjmp.S
+++ b/sysdeps/powerpc/bsd-setjmp.S
@@ -23,11 +23,14 @@
#include <sysdep.h>
-ENTRY (setjmp)
+ENTRY (__setjmp)
li 4,1 /* Set second argument to 1. */
#ifdef PIC
b __sigsetjmp@plt
#else
b __sigsetjmp
#endif
-END (setjmp)
+END (__setjmp)
+
+ .globl setjmp
+ .set setjmp,__setjmp
diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h
index 526887da18..ab22e46956 100644
--- a/sysdeps/powerpc/dl-machine.h
+++ b/sysdeps/powerpc/dl-machine.h
@@ -188,14 +188,21 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
finaladdr = reloc->r_addend;
}
else
- finaladdr = (loadbase + (Elf32_Word) (char *) sym->st_value +
- reloc->r_addend);
+ finaladdr = (loadbase + (Elf32_Word) (char *) sym->st_value
+ + reloc->r_addend);
}
/* This is an if/else if chain because GCC 2.7.2.[012] turns case
statements into non-PIC table lookups. When a later version
comes out that fixes this, this should be changed. */
- if (rinfo == R_PPC_ADDR16_LO)
+ if (rinfo == R_PPC_UADDR32 ||
+ rinfo == R_PPC_GLOB_DAT ||
+ rinfo == R_PPC_ADDR32 ||
+ rinfo == R_PPC_RELATIVE)
+ {
+ *reloc_addr = finaladdr;
+ }
+ else if (rinfo == R_PPC_ADDR16_LO)
{
*(Elf32_Half*) reloc_addr = finaladdr;
}
@@ -205,32 +212,29 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
}
else if (rinfo == R_PPC_ADDR16_HA)
{
- *(Elf32_Half*) reloc_addr = finaladdr + 0x8000 >> 16;
+ *(Elf32_Half*) reloc_addr = (finaladdr + 0x8000) >> 16;
}
+#ifndef RTLD_BOOTSTRAP
else if (rinfo == R_PPC_REL24)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
- assert (delta << 6 >> 6 == delta);
+ if (delta << 6 >> 6 != delta)
+ _dl_signal_error (0, map->l_name,
+ "R_PPC_REL24 relocation out of range");
*reloc_addr = *reloc_addr & 0xfc000003 | delta & 0x3fffffc;
}
- else if (rinfo == R_PPC_UADDR32 ||
- rinfo == R_PPC_GLOB_DAT ||
- rinfo == R_PPC_ADDR32 ||
- rinfo == R_PPC_RELATIVE)
- {
- *reloc_addr = finaladdr;
- }
else if (rinfo == R_PPC_ADDR24)
{
- assert (finaladdr << 6 >> 6 == finaladdr);
+ if (finaladdr << 6 >> 6 != finaladdr)
+ _dl_signal_error (0, map->l_name,
+ "R_PPC_ADDR24 relocation out of range");
*reloc_addr = *reloc_addr & 0xfc000003 | finaladdr & 0x3fffffc;
}
else if (rinfo == R_PPC_COPY)
{
- /* Memcpy is safe to use here, because ld.so doesn't have any
- COPY relocs (it's self-contained). */
memcpy (reloc_addr, (char *) finaladdr, sym->st_size);
}
+#endif
else if (rinfo == R_PPC_REL32)
{
*reloc_addr = finaladdr - (Elf32_Word) (char *) reloc_addr;
@@ -239,41 +243,44 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
if (delta << 6 >> 6 == delta)
- *reloc_addr = OPCODE_B(delta);
+ *reloc_addr = OPCODE_B (delta);
else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
- *reloc_addr = OPCODE_BA(finaladdr);
+ *reloc_addr = OPCODE_BA (finaladdr);
else
{
- Elf32_Word *plt = (Elf32_Word *)((char *)map->l_addr +
- map->l_info[DT_PLTGOT]->d_un.d_val);
- Elf32_Word index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
- Elf32_Word offset = index * 2 + PLT_INITIAL_ENTRY_WORDS;
+ Elf32_Word *plt;
+ Elf32_Word index;
+
+ plt = (Elf32_Word *)((char *)map->l_addr
+ + map->l_info[DT_PLTGOT]->d_un.d_val);
+ index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
if (index >= PLT_DOUBLE_SIZE)
{
- /* Slots greater than or equal to 2^13 have 4 words
- available instead of two. */
- plt[offset ] = OPCODE_LI (11,finaladdr);
- plt[offset+1] = OPCODE_ADDIS (11,11,finaladdr + 0x8000 >> 16);
- plt[offset+2] = OPCODE_MTCTR (11);
- plt[offset+3] = OPCODE_BCTR ();
+ /* Slots greater than or equal to 2^13 have 4 words available
+ instead of two. */
+ reloc_addr[0] = OPCODE_LI (11, finaladdr);
+ reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
+ reloc_addr[2] = OPCODE_MTCTR (11);
+ reloc_addr[3] = OPCODE_BCTR ();
}
else
{
Elf32_Word num_plt_entries;
- Elf32_Word rel_offset_words;
num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof(Elf32_Rela));
- rel_offset_words = PLT_DATA_START_WORDS (num_plt_entries);
- plt[offset ] = OPCODE_LI (11,index * 4);
- plt[offset+1] = OPCODE_B (-(4 * (offset + 1
- - PLT_LONGBRANCH_ENTRY_WORDS)));
- plt[index + rel_offset_words] = finaladdr;
+ reloc_addr[0] = OPCODE_LI (11, index*4);
+ reloc_addr[1] =
+ OPCODE_B (-(4*(index*2
+ + 1
+ - PLT_LONGBRANCH_ENTRY_WORDS
+ + PLT_INITIAL_ENTRY_WORDS)));
+ plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
}
}
- MODIFIED_CODE(reloc_addr);
+ MODIFIED_CODE (reloc_addr);
}
else
assert (! "unexpected dynamic reloc type");
@@ -295,7 +302,28 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
#define elf_machine_pltrel_p(type) ((type) == R_PPC_JMP_SLOT)
/* Set up the loaded object described by L so its unrelocated PLT
- entries will jump to the on-demand fixup code in dl-runtime.c. */
+ entries will jump to the on-demand fixup code in dl-runtime.c.
+ Also install a small trampoline to be used by entries that have
+ been relocated to an address too far away for a single branch. */
+
+/* A PLT entry does one of three things:
+ (i) Jumps to the actual routine. Such entries are set up above, in
+ elf_machine_rela.
+
+ (ii) Jumps to the actual routine via glue at the start of the PLT.
+ We do this by putting the address of the routine in space
+ allocated at the end of the PLT, and when the PLT entry is
+ called we load the offset of that word (from the start of the
+ space) into r11, then call the glue, which loads the word and
+ branches to that address. These entries are set up in
+ elf_machine_rela, but the glue is set up here.
+
+ (iii) Loads the index of this PLT entry (we count the double-size
+ entries as one entry for this purpose) into r11, then
+ branches to code at the start of the PLT. This code then
+ calls `fixup', in dl-runtime.c, via the glue in the macro
+ ELF_MACHINE_RUNTIME_TRAMPOLINE, which resets the PLT entry to
+ be one of the above two types. These entries are set up here. */
static inline void
elf_machine_runtime_setup (struct link_map *map, int lazy)
{
@@ -316,54 +344,78 @@ elf_machine_runtime_setup (struct link_map *map, int lazy)
if (lazy)
for (i = 0; i < num_plt_entries; i++)
{
- Elf32_Word offset = PLT_ENTRY_START_WORDS(i);
+ Elf32_Word offset = PLT_ENTRY_START_WORDS (i);
if (i >= PLT_DOUBLE_SIZE)
{
- plt[offset ] = OPCODE_LI (11, i * 4);
- plt[offset+1] = OPCODE_ADDIS (11, 11, i * 4 + 0x8000 >> 16);
+ plt[offset ] = OPCODE_LI (11, i * 4);
+ plt[offset+1] = OPCODE_ADDIS (11, 11, (i * 4 + 0x8000) >> 16);
plt[offset+2] = OPCODE_B (-(4 * (offset + 2)));
}
else
{
- plt[offset ] = OPCODE_LI (11, i * 4);
- plt[offset+1] = OPCODE_B(-(4 * (offset + 1)));
+ plt[offset ] = OPCODE_LI (11, i * 4);
+ plt[offset+1] = OPCODE_B (-(4 * (offset + 1)));
}
+ }
- /* Multiply index of entry, by 0xC. */
- plt[0] = OPCODE_SLWI (12, 11, 1);
- plt[1] = OPCODE_ADD (11, 12, 11);
- if ((Elf32_Word) (char *) _dl_runtime_resolve <= 0x01fffffc
- || (Elf32_Word) (char *) _dl_runtime_resolve >= 0xfe000000)
- {
- plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) map);
- plt[3] = OPCODE_ADDIS (12, 12,
- (Elf32_Word) (char *) map + 0x8000 >> 16);
- plt[4] = OPCODE_BA ((Elf32_Word) (char *) _dl_runtime_resolve);
- }
+ /* Multiply index of entry by 3 (in r11). */
+ plt[0] = OPCODE_SLWI (12, 11, 1);
+ plt[1] = OPCODE_ADD (11, 12, 11);
+ if ((Elf32_Word) (char *) _dl_runtime_resolve <= 0x01fffffc ||
+ (Elf32_Word) (char *) _dl_runtime_resolve >= 0xfe000000)
+ {
+ /* Load address of link map in r12. */
+ plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) map);
+ plt[3] = OPCODE_ADDIS (12, 12, (((Elf32_Word) (char *) map
+ + 0x8000) >> 16));
+
+ /* Call _dl_runtime_resolve. */
+ plt[4] = OPCODE_BA ((Elf32_Word) (char *) _dl_runtime_resolve);
}
else
{
+ /* Get address of _dl_runtime_resolve in CTR. */
plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) _dl_runtime_resolve);
- plt[3] = OPCODE_ADDIS(12, 12, 0x8000 +
- ((Elf32_Word) (char *) _dl_runtime_resolve
- >> 16));
+ plt[3] = OPCODE_ADDIS (12, 12, ((((Elf32_Word) (char *)
+ _dl_runtime_resolve)
+ + 0x8000) >> 16));
plt[4] = OPCODE_MTCTR (12);
+
+ /* Load address of link map in r12. */
plt[5] = OPCODE_LI (12, (Elf32_Word) (char *) map);
- plt[6] = OPCODE_ADDIS (12, 12, ((Elf32_Word) (char *) map
- + 0x8000 >> 16));
+ plt[6] = OPCODE_ADDIS (12, 12, (((Elf32_Word) (char *) map
+ + 0x8000) >> 16));
+
+ /* Call _dl_runtime_resolve. */
plt[7] = OPCODE_BCTR ();
}
+
+
+ /* Convert the index in r11 into an actual address, and get the
+ word at that address. */
plt[PLT_LONGBRANCH_ENTRY_WORDS] =
- OPCODE_ADDIS (11, 11, (Elf32_Word) (char*) (plt + rel_offset_words)
- + 0x8000 >> 16);
+ OPCODE_ADDIS (11, 11, (((Elf32_Word) (char*) (plt + rel_offset_words)
+ + 0x8000) >> 16));
plt[PLT_LONGBRANCH_ENTRY_WORDS+1] =
- OPCODE_LWZ(11,(Elf32_Word)(char*)(plt+rel_offset_words),11);
+ OPCODE_LWZ (11, (Elf32_Word) (char*) (plt+rel_offset_words), 11);
+
+ /* Call the procedure at that address. */
plt[PLT_LONGBRANCH_ENTRY_WORDS+2] = OPCODE_MTCTR (11);
plt[PLT_LONGBRANCH_ENTRY_WORDS+3] = OPCODE_BCTR ();
+
+ /* Now, we've modified code (quite a lot of code, possibly). We
+ need to write the changes from the data cache to a
+ second-level unified cache, then make sure that stale data in
+ the instruction cache is removed. (In a multiprocessor
+ system, the effect is more complex.)
+
+ Assumes the cache line size is at least 32 bytes, or at least
+ that dcbst and icbi apply to 32-byte lines. At present, all
+ PowerPC processors have line sizes of exactly 32 bytes. */
+
size_modified = lazy ? rel_offset_words : PLT_INITIAL_ENTRY_WORDS;
- /* Now we need to keep the caches in sync. */
for (i = 0; i < size_modified; i+=8)
PPC_DCBST (plt + i);
PPC_SYNC;
@@ -411,7 +463,7 @@ _dl_runtime_resolve:
# The code that calls this has put parameters for `fixup' in r12 and r11.
mr 3,12
mr 4,11
- bl fixup
+ bl fixup@local
# 'fixup' returns the address we want to branch to.
mtctr 3
# Put the registers back...
@@ -440,8 +492,9 @@ _dl_runtime_resolve:
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
#define RTLD_START \
+static ElfW(Addr) _dl_start (void *arg) __attribute__((unused)); \
asm ("\
- .text
+ .section \".text\"
.align 2
.globl _start
.type _start,@function
@@ -535,16 +588,34 @@ _start:
.previous
");
+/* The idea here is that to conform to the ABI, we are supposed to try
+ to load dynamic objects between 0x10000 (we actually use 0x40000 as
+ the lower bound, to increase the chance of a memory reference from
+ a null pointer giving a segfault) and the program's load address.
+ Regrettably, in this code we can't find the program's load address,
+ so we punt and choose 0x01800000, which is below the ABI's
+ recommended default, and what GNU ld currently chooses. We only use
+ the address as a preference for mmap, so if we get it wrong the
+ worst that happens is that it gets mapped somewhere else.
+
+ FIXME: Unfortunately, 'somewhere else' is probably right after the
+ program's break, which causes malloc to fail. We really need more
+ information here about the way memory is mapped. */
+
#define ELF_PREFERRED_ADDRESS_DATA \
-static ElfW(Addr) _dl_preferred_address = 0;
+static ElfW(Addr) _dl_preferred_address = 1;
#define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) \
( { \
ElfW(Addr) prefd; \
- if (mapstartpref != 0 && _dl_preferred_address == 0) \
+ if (mapstartpref != 0 && _dl_preferred_address == 1) \
_dl_preferred_address = mapstartpref; \
if (mapstartpref != 0) \
prefd = mapstartpref; \
+ else if (_dl_preferred_address == 1) \
+ prefd = _dl_preferred_address = \
+ (0x01800000 - maplength - 0x10000) & \
+ ~(_dl_pagesize - 1); \
else if (_dl_preferred_address < maplength + 0x50000) \
prefd = 0; \
else \
@@ -556,7 +627,7 @@ static ElfW(Addr) _dl_preferred_address = 0;
#define ELF_FIXED_ADDRESS(loader, mapstart) \
( { \
- if (mapstart != 0 && _dl_preferred_address < mapstart) \
+ if (mapstart != 0 && _dl_preferred_address == 1) \
_dl_preferred_address = mapstart; \
} )
diff --git a/sysdeps/powerpc/elf/start.c b/sysdeps/powerpc/elf/start.c
index 001d6aa97c..d32aeee6c7 100644
--- a/sysdeps/powerpc/elf/start.c
+++ b/sysdeps/powerpc/elf/start.c
@@ -29,6 +29,7 @@ asm ("\
.section \".text\"
.align 2
.globl _start
+ .type _start,@function
_start:
# save the stack pointer, in case we're statically linked under Linux
mr 8,1
diff --git a/sysdeps/powerpc/strlen.S b/sysdeps/powerpc/strlen.S
deleted file mode 100644
index 95eaf94de1..0000000000
--- a/sysdeps/powerpc/strlen.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Optimized strlen implementation for PowerPC.
- Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
- .section ".text"
- .align 2
- .globl strlen
- .type strlen,@function
-strlen:
- rlwinm 7,3,0,0,29
- lis 8,0x7f7f
- lwz 11,0(7)
- ori 8,8,32639
- rlwinm 4,3,3,27,28
- li 9,-1
- or 10,11,8
- and 0,11,8
- srw 9,9,4
- add 0,0,8
- nor 0,10,0
- and. 11,0,9
- bc 4,2,.L2
-.L3:
- lwzu 11,4(7)
- or 10,11,8
- and 0,11,8
- add 0,0,8
- nor. 11,10,0
- bc 12,2,.L3
-.L2:
- subf 0,3,7
- cntlzw 3,11
- srwi 3,3,3
- add 3,0,3
- blr
-.Lfe1:
- .size strlen,.Lfe1-strlen