sync with OpenBSD -current
This commit is contained in:
parent
25869dc67a
commit
14b4e966dd
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2012-2020 Alexander Bluhm <bluhm@openbsd.org>
|
||||
Copyright (c) 2012-2024 Alexander Bluhm <bluhm@openbsd.org>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.29 2023/09/08 21:15:02 bluhm Exp $
|
||||
# $OpenBSD: Makefile,v 1.30 2024/03/12 21:31:29 bluhm Exp $
|
||||
|
||||
# The following ports must be installed:
|
||||
#
|
||||
@ -88,7 +88,11 @@ stamp-pf: addr.py pf.conf
|
||||
FRAG6_SCRIPTS !!= cd ${.CURDIR} && ls -1 frag6*.py
|
||||
|
||||
run-stack-frag6_queuelimit.py:
|
||||
# the stack does not limit the amount of fragments during reassembly
|
||||
# stack does not limit the amount of fragments during reassembly
|
||||
@echo DISABLED
|
||||
|
||||
run-pf-frag6_oversize.py run-pf-frag6_unfragsize.py:
|
||||
# pf does not send icmp parameter problem, so test does not work
|
||||
@echo DISABLED
|
||||
|
||||
run-stack-frag6_doubleatomic.py: addr.py stamp-stack
|
||||
|
65
regress/sys/netinet6/frag6/frag6_oversize.py
Normal file
65
regress/sys/netinet6/frag6/frag6_oversize.py
Normal file
@ -0,0 +1,65 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
print("ping6 fragments in total larger than IP maximum packet")
|
||||
|
||||
# |---------|
|
||||
# |--------|
|
||||
# ... ...
|
||||
# |--------|
|
||||
|
||||
import os
|
||||
from addr import *
|
||||
from scapy.all import *
|
||||
|
||||
pid=os.getpid()
|
||||
eid=pid & 0xffff
|
||||
payload=b"ABCDEFGHIJKLMNOP"
|
||||
packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \
|
||||
ICMPv6EchoRequest(id=eid, data=4095*payload)
|
||||
plen=IPv6(raw(packet)).plen
|
||||
print("plen=%u" % (plen))
|
||||
if plen != 0xfff8:
|
||||
print("PLEN!=%u" % (0xfff8))
|
||||
exit(2)
|
||||
bytes=bytes(packet)+b"12345678"
|
||||
|
||||
frag=[]
|
||||
fid=pid & 0xffffffff
|
||||
frag.append(IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10])
|
||||
off=2**7
|
||||
while off < 2**13:
|
||||
frag.append(IPv6ExtHdrFragment(nh=58, id=fid, offset=off)/ \
|
||||
bytes[40+off*8:40+off*8+2**10])
|
||||
off+=2**7
|
||||
eth=[]
|
||||
for f in frag:
|
||||
pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f
|
||||
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt)
|
||||
|
||||
if os.fork() == 0:
|
||||
time.sleep(1)
|
||||
sendp(eth, iface=LOCAL_IF)
|
||||
os._exit(0)
|
||||
|
||||
ans=sniff(iface=LOCAL_IF, timeout=3, filter=
|
||||
"ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6")
|
||||
for a in ans:
|
||||
print("type %d" % (a.payload.payload.type))
|
||||
print("icmp %s" % (icmp6types[a.payload.payload.type]))
|
||||
if a and a.type == ETH_P_IPV6 and \
|
||||
ipv6nh[a.payload.nh] == 'ICMPv6' and \
|
||||
icmp6types[a.payload.payload.type] == 'Parameter problem':
|
||||
print("code=%u" % (a.payload.payload.code))
|
||||
# 0: 'erroneous header field encountered'
|
||||
if a.payload.payload.code != 0:
|
||||
print("WRONG PARAMETER PROBLEM CODE")
|
||||
exit(1)
|
||||
ptr=a.payload.payload.ptr
|
||||
print("ptr=%u" % (ptr))
|
||||
# 42: sizeof IPv6 header + offset in fragment header
|
||||
if ptr != 42:
|
||||
print("PTR!=%u" % (ptr))
|
||||
exit(1)
|
||||
exit(0)
|
||||
print("NO ICMP PARAMETER PROBLEM")
|
||||
exit(2)
|
77
regress/sys/netinet6/frag6/frag6_unfragsize.py
Normal file
77
regress/sys/netinet6/frag6/frag6_unfragsize.py
Normal file
@ -0,0 +1,77 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
print("ping6 fragments with options total larger than IP maximum packet")
|
||||
|
||||
# |--------|
|
||||
# ... ...
|
||||
# |--------|
|
||||
# drop first fragment with ECN conflict, reinsert with longer unfrag part
|
||||
# |---------|
|
||||
# HopByHop|---------|
|
||||
|
||||
import os
|
||||
from addr import *
|
||||
from scapy.all import *
|
||||
|
||||
pid=os.getpid()
|
||||
eid=pid & 0xffff
|
||||
payload=b"ABCDEFGHIJKLMNOP"
|
||||
packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \
|
||||
ICMPv6EchoRequest(id=eid, data=4095*payload)
|
||||
plen=IPv6(raw(packet)).plen
|
||||
print("plen=%u" % (plen))
|
||||
if plen != 0xfff8:
|
||||
print("PLEN!=%u" % (0xfff8))
|
||||
exit(2)
|
||||
bytes=bytes(packet)
|
||||
|
||||
frag=[]
|
||||
fid=pid & 0xffffffff
|
||||
off=2**7
|
||||
while off < 2**13:
|
||||
frag.append(IPv6ExtHdrFragment(nh=58, id=fid, offset=off)/ \
|
||||
bytes[40+off*8:40+off*8+2**10])
|
||||
off+=2**7
|
||||
eth=[]
|
||||
for f in frag:
|
||||
pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f
|
||||
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt)
|
||||
|
||||
# first fragment with ECN to be dropped
|
||||
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/
|
||||
IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6, tc=3)/
|
||||
IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10])
|
||||
|
||||
# resend first fragment with unfragmentable part too long for IP plen
|
||||
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/
|
||||
IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/
|
||||
IPv6ExtHdrHopByHop(options=PadN(optdata="\0"*4))/
|
||||
IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10])
|
||||
|
||||
if os.fork() == 0:
|
||||
time.sleep(1)
|
||||
sendp(eth, iface=LOCAL_IF)
|
||||
os._exit(0)
|
||||
|
||||
ans=sniff(iface=LOCAL_IF, timeout=3, filter=
|
||||
"ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6")
|
||||
for a in ans:
|
||||
print("type %d" % (a.payload.payload.type))
|
||||
print("icmp %s" % (icmp6types[a.payload.payload.type]))
|
||||
if a and a.type == ETH_P_IPV6 and \
|
||||
ipv6nh[a.payload.nh] == 'ICMPv6' and \
|
||||
icmp6types[a.payload.payload.type] == 'Parameter problem':
|
||||
print("code=%u" % (a.payload.payload.code))
|
||||
# 0: 'erroneous header field encountered'
|
||||
if a.payload.payload.code != 0:
|
||||
print("WRONG PARAMETER PROBLEM CODE")
|
||||
exit(1)
|
||||
ptr=a.payload.payload.ptr
|
||||
print("ptr=%u" % (ptr))
|
||||
# 42: sizeof IPv6 header + offset in fragment header
|
||||
if ptr != 42:
|
||||
print("PTR!=%u" % (ptr))
|
||||
exit(1)
|
||||
exit(0)
|
||||
print("NO ICMP PARAMETER PROBLEM")
|
||||
exit(2)
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: gadget.S,v 1.1 2023/01/09 11:50:01 anton Exp $ */
|
||||
/* $OpenBSD: gadget.S,v 1.2 2024/03/13 11:18:42 kettenis Exp $ */
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <machine/asm.h>
|
||||
@ -12,11 +12,13 @@
|
||||
.type gadget_getpid,_ASM_TYPE_FUNCTION
|
||||
gadget_getpid:
|
||||
#if defined(__amd64__)
|
||||
endbr64
|
||||
mov $SYS_getpid, %eax
|
||||
syscall
|
||||
ret
|
||||
#elif defined(__aarch64__)
|
||||
ldr x8, #SYS_getpid
|
||||
bti c
|
||||
mov x8, #SYS_getpid
|
||||
svc 0
|
||||
dsb nsh
|
||||
isb
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: machdep.c,v 1.86 2024/02/21 01:45:14 dlg Exp $ */
|
||||
/* $OpenBSD: machdep.c,v 1.87 2024/03/13 14:57:08 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
|
||||
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
|
||||
@ -366,6 +366,7 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
|
||||
return sysctl_rdquad(oldp, oldlenp, newp, value);
|
||||
case CPU_ID_AA64PFR1:
|
||||
value = 0;
|
||||
value |= cpu_id_aa64pfr1 & ID_AA64PFR1_BT_MASK;
|
||||
value |= cpu_id_aa64pfr1 & ID_AA64PFR1_SBSS_MASK;
|
||||
return sysctl_rdquad(oldp, oldlenp, newp, value);
|
||||
case CPU_ID_AA64ISAR2:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: GENERIC,v 1.294 2024/03/10 13:25:10 jsg Exp $
|
||||
# $OpenBSD: GENERIC,v 1.295 2024/03/13 14:43:31 bluhm Exp $
|
||||
#
|
||||
# Machine-independent option; used by all architectures for their
|
||||
# GENERIC kernel
|
||||
@ -16,7 +16,7 @@ option KMEMSTATS # collect malloc(9) statistics
|
||||
option PTRACE # ptrace(2) system call
|
||||
|
||||
#option KVA_GUARDPAGES # slow virtual address recycling (+ guarding)
|
||||
#option POOL_DEBUG # pool corruption detection
|
||||
option POOL_DEBUG # pool corruption detection
|
||||
#option VFSLCKDEBUG # VFS locking checks
|
||||
|
||||
option CRYPTO # Cryptographic framework
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: dt_prov_profile.c,v 1.6 2024/02/09 17:42:18 cheloha Exp $ */
|
||||
/* $OpenBSD: dt_prov_profile.c,v 1.7 2024/03/13 13:13:57 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
|
||||
@ -53,13 +53,13 @@ int
|
||||
dt_prov_profile_init(void)
|
||||
{
|
||||
dtpp_profile = dt_dev_alloc_probe("hz", "97", &dt_prov_profile);
|
||||
dt_dev_register_probe(dtpp_profile);
|
||||
if (dtpp_profile == NULL)
|
||||
return 0;
|
||||
dt_dev_register_probe(dtpp_profile);
|
||||
dtpp_interval = dt_dev_alloc_probe("hz", "1", &dt_prov_interval);
|
||||
dt_dev_register_probe(dtpp_interval);
|
||||
if (dtpp_interval == NULL)
|
||||
return 1;
|
||||
dt_dev_register_probe(dtpp_interval);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: tmux.1,v 1.936 2024/02/13 08:10:23 nicm Exp $
|
||||
.\" $OpenBSD: tmux.1,v 1.937 2024/03/13 11:25:50 nicm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 13 2024 $
|
||||
.Dd $Mdocdate: March 13 2024 $
|
||||
.Dt TMUX 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1036,9 +1036,17 @@ The following commands are available to manage clients and sessions:
|
||||
.D1 Pq alias: Ic attach
|
||||
If run from outside
|
||||
.Nm ,
|
||||
create a new client in the current terminal and attach it to
|
||||
attach to
|
||||
.Ar target-session
|
||||
in the current terminal.
|
||||
.Ar target-session
|
||||
must already exist - to create a new session, see the
|
||||
.Ic new-session
|
||||
command (with
|
||||
.Fl A
|
||||
to create or attach).
|
||||
If used from inside, switch the currently attached session to
|
||||
.Ar target-session .
|
||||
If used from inside, switch the current client.
|
||||
If
|
||||
.Fl d
|
||||
is specified, any other clients attached to the session are detached.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ksyms.c,v 1.6 2023/11/10 18:56:21 jasper Exp $ */
|
||||
/* $OpenBSD: ksyms.c,v 1.7 2024/03/12 17:22:24 cheloha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
|
||||
@ -23,6 +23,7 @@
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -30,60 +31,149 @@
|
||||
|
||||
#include "btrace.h"
|
||||
|
||||
struct syms {
|
||||
int fd;
|
||||
Elf *elf;
|
||||
Elf_Scn *symtab;
|
||||
size_t strtabndx, nsymb;
|
||||
struct sym {
|
||||
char *sym_name;
|
||||
unsigned long sym_value; /* from st_value */
|
||||
unsigned long sym_size; /* from st_size */
|
||||
};
|
||||
|
||||
int kelf_parse(struct syms *);
|
||||
struct syms {
|
||||
struct sym *table;
|
||||
size_t nsymb;
|
||||
};
|
||||
|
||||
int sym_compare_search(const void *, const void *);
|
||||
int sym_compare_sort(const void *, const void *);
|
||||
|
||||
struct syms *
|
||||
kelf_open(const char *path)
|
||||
{
|
||||
struct syms *syms;
|
||||
int error;
|
||||
char *name;
|
||||
Elf *elf;
|
||||
Elf_Data *data = NULL;
|
||||
Elf_Scn *scn = NULL, *symtab;
|
||||
GElf_Sym sym;
|
||||
GElf_Shdr shdr;
|
||||
size_t i, shstrndx, strtabndx = SIZE_MAX, symtab_size;
|
||||
unsigned long diff;
|
||||
struct sym *tmp;
|
||||
struct syms *syms = NULL;
|
||||
int fd;
|
||||
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
errx(1, "elf_version: %s", elf_errmsg(-1));
|
||||
|
||||
if ((syms = calloc(1, sizeof(*syms))) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
syms->fd = open(path, O_RDONLY);
|
||||
if (syms->fd == -1) {
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
warn("open: %s", path);
|
||||
free(syms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((syms->elf = elf_begin(syms->fd, ELF_C_READ, NULL)) == NULL) {
|
||||
if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
|
||||
warnx("elf_begin: %s", elf_errmsg(-1));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (elf_kind(syms->elf) != ELF_K_ELF)
|
||||
if (elf_kind(elf) != ELF_K_ELF)
|
||||
goto bad;
|
||||
|
||||
error = kelf_parse(syms);
|
||||
if (error)
|
||||
if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
|
||||
warnx("elf_getshdrstrndx: %s", elf_errmsg(-1));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
while ((scn = elf_nextscn(elf, scn)) != NULL) {
|
||||
if (gelf_getshdr(scn, &shdr) != &shdr) {
|
||||
warnx("elf_getshdr: %s", elf_errmsg(-1));
|
||||
goto bad;
|
||||
}
|
||||
if ((name = elf_strptr(elf, shstrndx, shdr.sh_name)) == NULL) {
|
||||
warnx("elf_strptr: %s", elf_errmsg(-1));
|
||||
goto bad;
|
||||
}
|
||||
if (strcmp(name, ELF_SYMTAB) == 0 &&
|
||||
shdr.sh_type == SHT_SYMTAB && shdr.sh_entsize != 0) {
|
||||
symtab = scn;
|
||||
symtab_size = shdr.sh_size / shdr.sh_entsize;
|
||||
}
|
||||
if (strcmp(name, ELF_STRTAB) == 0 &&
|
||||
shdr.sh_type == SHT_STRTAB) {
|
||||
strtabndx = elf_ndxscn(scn);
|
||||
}
|
||||
}
|
||||
if (symtab == NULL) {
|
||||
warnx("%s: %s: section not found", path, ELF_SYMTAB);
|
||||
goto bad;
|
||||
}
|
||||
if (strtabndx == SIZE_MAX) {
|
||||
warnx("%s: %s: section not found", path, ELF_STRTAB);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
data = elf_rawdata(symtab, data);
|
||||
if (data == NULL)
|
||||
goto bad;
|
||||
|
||||
return syms;
|
||||
if ((syms = calloc(1, sizeof(*syms))) == NULL)
|
||||
err(1, NULL);
|
||||
syms->table = calloc(symtab_size, sizeof *syms->table);
|
||||
if (syms->table == NULL)
|
||||
err(1, NULL);
|
||||
for (i = 0; i < symtab_size; i++) {
|
||||
if (gelf_getsym(data, i, &sym) == NULL)
|
||||
continue;
|
||||
if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
|
||||
continue;
|
||||
name = elf_strptr(elf, strtabndx, sym.st_name);
|
||||
if (name == NULL)
|
||||
continue;
|
||||
syms->table[syms->nsymb].sym_name = strdup(name);
|
||||
if (syms->table[syms->nsymb].sym_name == NULL)
|
||||
err(1, NULL);
|
||||
syms->table[syms->nsymb].sym_value = sym.st_value;
|
||||
syms->table[syms->nsymb].sym_size = sym.st_size;
|
||||
syms->nsymb++;
|
||||
}
|
||||
tmp = reallocarray(syms->table, syms->nsymb, sizeof *syms->table);
|
||||
if (tmp == NULL)
|
||||
err(1, NULL);
|
||||
syms->table = tmp;
|
||||
|
||||
/* Sort symbols in ascending order by address. */
|
||||
qsort(syms->table, syms->nsymb, sizeof *syms->table, sym_compare_sort);
|
||||
|
||||
/*
|
||||
* Some functions, particularly those written in assembly, have an
|
||||
* st_size of zero. We can approximate a size for these by assuming
|
||||
* that they extend from their st_value to that of the next function.
|
||||
*/
|
||||
for (i = 0; i < syms->nsymb; i++) {
|
||||
if (syms->table[i].sym_size != 0)
|
||||
continue;
|
||||
/* Can't do anything for the last symbol. */
|
||||
if (i + 1 == syms->nsymb)
|
||||
continue;
|
||||
diff = syms->table[i + 1].sym_value - syms->table[i].sym_value;
|
||||
syms->table[i].sym_size = diff;
|
||||
}
|
||||
|
||||
bad:
|
||||
kelf_close(syms);
|
||||
return NULL;
|
||||
elf_end(elf);
|
||||
close(fd);
|
||||
return syms;
|
||||
}
|
||||
|
||||
void
|
||||
kelf_close(struct syms *syms)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (syms == NULL)
|
||||
return;
|
||||
elf_end(syms->elf);
|
||||
close(syms->fd);
|
||||
|
||||
for (i = 0; i < syms->nsymb; i++)
|
||||
free(syms->table[i].sym_name);
|
||||
free(syms->table);
|
||||
free(syms);
|
||||
}
|
||||
|
||||
@ -91,106 +181,46 @@ int
|
||||
kelf_snprintsym(struct syms *syms, char *str, size_t size, unsigned long pc,
|
||||
unsigned long off)
|
||||
{
|
||||
GElf_Sym sym;
|
||||
Elf_Data *data = NULL;
|
||||
Elf_Addr offset, bestoff = 0;
|
||||
size_t i, bestidx = 0;
|
||||
char *name;
|
||||
int cnt;
|
||||
struct sym key = { .sym_value = pc + off };
|
||||
struct sym *entry;
|
||||
Elf_Addr offset;
|
||||
|
||||
if (syms == NULL)
|
||||
goto fallback;
|
||||
|
||||
data = elf_rawdata(syms->symtab, data);
|
||||
if (data == NULL)
|
||||
entry = bsearch(&key, syms->table, syms->nsymb, sizeof *syms->table,
|
||||
sym_compare_search);
|
||||
if (entry == NULL)
|
||||
goto fallback;
|
||||
|
||||
for (i = 0; i < syms->nsymb; i++) {
|
||||
if (gelf_getsym(data, i, &sym) == NULL)
|
||||
continue;
|
||||
if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
|
||||
continue;
|
||||
if (pc >= sym.st_value + off) {
|
||||
if (pc < (sym.st_value + off + sym.st_size))
|
||||
break;
|
||||
/* Workaround for symbols w/o size, usually asm ones. */
|
||||
if (sym.st_size == 0 && sym.st_value + off > bestoff) {
|
||||
bestidx = i;
|
||||
bestoff = sym.st_value + off;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == syms->nsymb) {
|
||||
if (bestidx == 0 || gelf_getsym(data, bestidx, &sym) == NULL)
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
name = elf_strptr(syms->elf, syms->strtabndx, sym.st_name);
|
||||
if (name != NULL)
|
||||
cnt = snprintf(str, size, "\n%s", name);
|
||||
else
|
||||
cnt = snprintf(str, size, "\n0x%llx", sym.st_value);
|
||||
if (cnt < 0)
|
||||
return cnt;
|
||||
|
||||
offset = pc - (sym.st_value + off);
|
||||
offset = pc - (entry->sym_value + off);
|
||||
if (offset != 0) {
|
||||
int l;
|
||||
|
||||
l = snprintf(str + cnt, size > (size_t)cnt ? size - cnt : 0,
|
||||
"+0x%llx", (unsigned long long)offset);
|
||||
if (l < 0)
|
||||
return l;
|
||||
cnt += l;
|
||||
return snprintf(str, size, "\n%s+0x%llx",
|
||||
entry->sym_name, (unsigned long long)offset);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
return snprintf(str, size, "\n%s", entry->sym_name);
|
||||
|
||||
fallback:
|
||||
return snprintf(str, size, "\n0x%lx", pc);
|
||||
}
|
||||
|
||||
int
|
||||
kelf_parse(struct syms *syms)
|
||||
sym_compare_sort(const void *ap, const void *bp)
|
||||
{
|
||||
GElf_Shdr shdr;
|
||||
Elf_Scn *scn, *scnctf;
|
||||
char *name;
|
||||
size_t shstrndx;
|
||||
const struct sym *a = ap, *b = bp;
|
||||
|
||||
if (elf_getshdrstrndx(syms->elf, &shstrndx) != 0) {
|
||||
warnx("elf_getshdrstrndx: %s", elf_errmsg(-1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
scn = scnctf = NULL;
|
||||
while ((scn = elf_nextscn(syms->elf, scn)) != NULL) {
|
||||
if (gelf_getshdr(scn, &shdr) != &shdr) {
|
||||
warnx("elf_getshdr: %s", elf_errmsg(-1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((name = elf_strptr(syms->elf, shstrndx,
|
||||
shdr.sh_name)) == NULL) {
|
||||
warnx("elf_strptr: %s", elf_errmsg(-1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(name, ELF_SYMTAB) == 0 &&
|
||||
shdr.sh_type == SHT_SYMTAB && shdr.sh_entsize != 0) {
|
||||
syms->symtab = scn;
|
||||
syms->nsymb = shdr.sh_size / shdr.sh_entsize;
|
||||
}
|
||||
|
||||
if (strcmp(name, ELF_STRTAB) == 0 &&
|
||||
shdr.sh_type == SHT_STRTAB) {
|
||||
syms->strtabndx = elf_ndxscn(scn);
|
||||
}
|
||||
}
|
||||
|
||||
if (syms->symtab == NULL)
|
||||
warnx("symbol table not found");
|
||||
|
||||
return 0;
|
||||
if (a->sym_value < b->sym_value)
|
||||
return -1;
|
||||
return a->sym_value > b->sym_value;
|
||||
}
|
||||
|
||||
int
|
||||
sym_compare_search(const void *keyp, const void *entryp)
|
||||
{
|
||||
const struct sym *entry = entryp, *key = keyp;
|
||||
|
||||
if (key->sym_value < entry->sym_value)
|
||||
return -1;
|
||||
return key->sym_value >= entry->sym_value + entry->sym_size;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user